| /* |
| ******************************************************************************* |
| * 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; |
| } |
| } |
| } |