blob: 34d65e25427d9193be5c414cfc4f356cb8cd2e18 [file] [log] [blame]
/*
*******************************************************************************
* Copyright (C) 1998-2004, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
* Created on Dec 3, 2003
*
*******************************************************************************
*/
package com.ibm.icu.dev.tool.layout;
import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.lang.UProperty;
public class ArabicShaping {
// arabic shaping type code
// shaping bit masks
static final int MASK_SHAPE_RIGHT = 1; // if this bit set, shapes to right
static final int MASK_SHAPE_LEFT = 2; // if this bit set, shapes to left
static final int MASK_TRANSPARENT = 4; // if this bit set, is transparent (ignore other bits)
static final int MASK_NOSHAPE = 8; // if this bit set, don't shape this char, i.e. tatweel
// shaping values
public static final int VALUE_NONE = 0;
public static final int VALUE_RIGHT = MASK_SHAPE_RIGHT;
public static final int VALUE_LEFT = MASK_SHAPE_LEFT;
public static final int VALUE_DUAL = MASK_SHAPE_RIGHT | MASK_SHAPE_LEFT;
public static final int VALUE_TRANSPARENT = MASK_TRANSPARENT;
public static final int VALUE_NOSHAPE_DUAL = MASK_NOSHAPE | VALUE_DUAL;
public static final int VALUE_NOSHAPE_NONE = MASK_NOSHAPE;
public static int getShapeType(char ch)
{
int tt = UCharacter.getIntPropertyValue(ch, UProperty.JOINING_TYPE);
switch(tt) {
case UCharacter.JoiningType.JOIN_CAUSING:
return VALUE_NOSHAPE_DUAL;
case UCharacter.JoiningType.LEFT_JOINING:
return VALUE_LEFT;
case UCharacter.JoiningType.RIGHT_JOINING:
return VALUE_RIGHT;
case UCharacter.JoiningType.DUAL_JOINING:
return VALUE_DUAL;
case UCharacter.JoiningType.TRANSPARENT:
return VALUE_TRANSPARENT;
case UCharacter.JoiningType.NON_JOINING:
default:
return VALUE_NOSHAPE_NONE;
}
}
/*
* Chars in logical order.
* leftType is shaping code of char to logical left of range
* rightType is shaping code of char to logical right of range
*/
public static void shape(char[] chars, int leftType, int rightType, ClassTable isolClassTable) {
// iterate in logical order from left to right
//
// the effective right char is the most recently encountered
// non-transparent char
//
// four boolean states:
// the effective right char shapes
// the effective right char causes right shaping
// the current char shapes
// the current char causes left shaping
//
// if both cause shaping, then
// right += 2 (isolate to initial, or final to medial)
// cur += 1 (isolate to final)
// ern is effective right logical index
int ern = -1;
boolean rightShapes = false;
boolean rightCauses = (rightType & MASK_SHAPE_LEFT) != 0;
for (int n = 0; n < chars.length; n++) {
char c = chars[n];
int t = getShapeType(c);
if ((t & MASK_TRANSPARENT) != 0) {
continue;
}
boolean curShapes = (t & MASK_NOSHAPE) == 0;
boolean curCauses = (t & MASK_SHAPE_RIGHT) != 0;
if (rightCauses && curCauses) {
if (rightShapes) {
chars[ern] += 2;
}
if (curShapes) {
chars[n] = (char) (isolClassTable.getGlyphClassID(c) + 1);
}
} else {
if (curShapes) {
chars[n] = (char) isolClassTable.getGlyphClassID(c);
}
}
rightShapes = curShapes;
rightCauses = (t & MASK_SHAPE_LEFT) != 0;
ern = n;
}
if (rightShapes && rightCauses && (leftType & MASK_SHAPE_RIGHT) != 0) {
chars[ern] += 2;
}
}
}