1 /* 2 ******************************************************************************* 3 * Copyright (C) 1998-2004, International Business Machines Corporation and * 4 * others. All Rights Reserved. * 5 ******************************************************************************* 6 * 7 * Created on Dec 3, 2003 8 * 9 ******************************************************************************* 10 */ 11 package com.ibm.icu.dev.tool.layout; 12 13 import com.ibm.icu.lang.UCharacter; 14 import com.ibm.icu.lang.UProperty; 15 16 public class ArabicShaping { 17 18 // arabic shaping type code 19 20 // shaping bit masks 21 static final int MASK_SHAPE_RIGHT = 1; // if this bit set, shapes to right 22 static final int MASK_SHAPE_LEFT = 2; // if this bit set, shapes to left 23 static final int MASK_TRANSPARENT = 4; // if this bit set, is transparent (ignore other bits) 24 static final int MASK_NOSHAPE = 8; // if this bit set, don't shape this char, i.e. tatweel 25 26 // shaping values 27 public static final int VALUE_NONE = 0; 28 public static final int VALUE_RIGHT = MASK_SHAPE_RIGHT; 29 public static final int VALUE_LEFT = MASK_SHAPE_LEFT; 30 public static final int VALUE_DUAL = MASK_SHAPE_RIGHT | MASK_SHAPE_LEFT; 31 public static final int VALUE_TRANSPARENT = MASK_TRANSPARENT; 32 public static final int VALUE_NOSHAPE_DUAL = MASK_NOSHAPE | VALUE_DUAL; 33 public static final int VALUE_NOSHAPE_NONE = MASK_NOSHAPE; 34 getShapeType(char ch)35 public static int getShapeType(char ch) 36 { 37 int tt = UCharacter.getIntPropertyValue(ch, UProperty.JOINING_TYPE); 38 39 switch(tt) { 40 case UCharacter.JoiningType.JOIN_CAUSING: 41 return VALUE_NOSHAPE_DUAL; 42 43 case UCharacter.JoiningType.LEFT_JOINING: 44 return VALUE_LEFT; 45 46 case UCharacter.JoiningType.RIGHT_JOINING: 47 return VALUE_RIGHT; 48 49 case UCharacter.JoiningType.DUAL_JOINING: 50 return VALUE_DUAL; 51 52 case UCharacter.JoiningType.TRANSPARENT: 53 return VALUE_TRANSPARENT; 54 55 case UCharacter.JoiningType.NON_JOINING: 56 default: 57 return VALUE_NOSHAPE_NONE; 58 } 59 } 60 61 /* 62 * Chars in logical order. 63 * leftType is shaping code of char to logical left of range 64 * rightType is shaping code of char to logical right of range 65 */ 66 shape(char[] chars, int leftType, int rightType, ClassTable isolClassTable)67 public static void shape(char[] chars, int leftType, int rightType, ClassTable isolClassTable) { 68 // iterate in logical order from left to right 69 // 70 // the effective right char is the most recently encountered 71 // non-transparent char 72 // 73 // four boolean states: 74 // the effective right char shapes 75 // the effective right char causes right shaping 76 // the current char shapes 77 // the current char causes left shaping 78 // 79 // if both cause shaping, then 80 // right += 2 (isolate to initial, or final to medial) 81 // cur += 1 (isolate to final) 82 83 // ern is effective right logical index 84 int ern = -1; 85 86 boolean rightShapes = false; 87 boolean rightCauses = (rightType & MASK_SHAPE_LEFT) != 0; 88 89 for (int n = 0; n < chars.length; n++) { 90 char c = chars[n]; 91 int t = getShapeType(c); 92 93 if ((t & MASK_TRANSPARENT) != 0) { 94 continue; 95 } 96 97 boolean curShapes = (t & MASK_NOSHAPE) == 0; 98 boolean curCauses = (t & MASK_SHAPE_RIGHT) != 0; 99 100 if (rightCauses && curCauses) { 101 if (rightShapes) { 102 chars[ern] += 2; 103 } 104 105 if (curShapes) { 106 chars[n] = (char) (isolClassTable.getGlyphClassID(c) + 1); 107 } 108 } else { 109 if (curShapes) { 110 chars[n] = (char) isolClassTable.getGlyphClassID(c); 111 } 112 } 113 114 rightShapes = curShapes; 115 rightCauses = (t & MASK_SHAPE_LEFT) != 0; 116 ern = n; 117 } 118 119 if (rightShapes && rightCauses && (leftType & MASK_SHAPE_RIGHT) != 0) { 120 chars[ern] += 2; 121 } 122 } 123 } 124