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