1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
|
diff -ur icu-49.1.orig/source/layout/ArabicShaping.cpp icu-49.1/source/layout/ArabicShaping.cpp
--- icu-49.1.orig/source/layout/ArabicShaping.cpp 2012-03-21 18:38:10.000000000 +0100
+++ icu-49.1/source/layout/ArabicShaping.cpp 2012-03-22 10:21:21.000000000 +0100
@@ -24,6 +24,31 @@
ArabicShaping::ST_TRANSPARENT // [T]
};
+// Draft Mongolian shaping classes, not provided by the Unicode data files at this time
+enum {
+ _c_ = ArabicShaping::ST_NOSHAPE_DUAL,
+ _d_ = ArabicShaping::ST_DUAL,
+ _n_ = ArabicShaping::ST_NONE,
+ _r_ = ArabicShaping::ST_RIGHT,
+ _t_ = ArabicShaping::ST_TRANSPARENT,
+ _x_ = ArabicShaping::ST_NOSHAPE_NONE
+};
+
+const ArabicShaping::ShapeType ArabicShaping::mongolianTypes[] =
+{
+ _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _t_, _t_, _t_, _t_, _n_, // 0x1800 - 0x180f
+ _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, // 0x1810 - 0x181f
+ _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, // 0x1820 - 0x182f
+ _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, // 0x1830 - 0x183f
+ _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, // 0x1840 - 0x184f
+ _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, // 0x1850 - 0x185f
+ _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, // 0x1860 - 0x186f
+ _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, // 0x1870 - 0x187f
+ _n_, _n_, _n_, _n_, _n_, _n_, _n_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, // 0x1880 - 0x188f
+ _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, // 0x1890 - 0x189f
+ _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _t_, _n_, _n_, _n_, _n_, _n_, _n_ // 0x18a0 - 0x18af
+};
+
/*
shaping array holds types for Arabic chars between 0610 and 0700
other values are either unshaped, or transparent if a mark or format
@@ -36,6 +61,18 @@
const ClassDefinitionTable *joiningTypes = (const ClassDefinitionTable *) ArabicShaping::shapingTypeTable;
le_int32 joiningType = joiningTypes->getGlyphClass(c);
+ if (joiningType == ArabicShaping::JT_RIGHT_JOINING) { // check for Syriac exceptions ALAPH, DALATH, RISH
+ if (c == 0x0710)
+ return ArabicShaping::ST_ALAPH;
+ if (c == 0x0715 || c == 0x0716 || c == 0x072A || c == 0x072F)
+ return ArabicShaping::ST_DALATH_RISH;
+ }
+
+ if (joiningType == 0) { // check for Mongolian range, not supported by ArabicShaping::shapingTypeTable
+ if (c >= 0x1800 && c <= 0x18af)
+ return ArabicShaping::mongolianTypes[c - 0x1800];
+ }
+
if (joiningType >= 0 && joiningType < ArabicShaping::JT_COUNT) {
return ArabicShaping::shapeTypes[joiningType];
}
@@ -46,7 +83,10 @@
#define isolFeatureTag LE_ISOL_FEATURE_TAG
#define initFeatureTag LE_INIT_FEATURE_TAG
#define mediFeatureTag LE_MEDI_FEATURE_TAG
+#define med2FeatureTag LE_MED2_FEATURE_TAG
#define finaFeatureTag LE_FINA_FEATURE_TAG
+#define fin2FeatureTag LE_FIN2_FEATURE_TAG
+#define fin3FeatureTag LE_FIN3_FEATURE_TAG
#define ligaFeatureTag LE_LIGA_FEATURE_TAG
#define msetFeatureTag LE_MSET_FEATURE_TAG
#define markFeatureTag LE_MARK_FEATURE_TAG
@@ -62,33 +102,40 @@
// NOTE:
// The isol, fina, init and medi features must be
// defined in the above order, and have masks that
-// are all in the same nibble.
+// are all in the same byte.
#define isolFeatureMask 0x80000000UL
#define finaFeatureMask 0x40000000UL
#define initFeatureMask 0x20000000UL
#define mediFeatureMask 0x10000000UL
-#define ccmpFeatureMask 0x08000000UL
-#define rligFeatureMask 0x04000000UL
-#define caltFeatureMask 0x02000000UL
-#define ligaFeatureMask 0x01000000UL
-#define dligFeatureMask 0x00800000UL
-#define cswhFeatureMask 0x00400000UL
-#define msetFeatureMask 0x00200000UL
-#define cursFeatureMask 0x00100000UL
-#define kernFeatureMask 0x00080000UL
-#define markFeatureMask 0x00040000UL
-#define mkmkFeatureMask 0x00020000UL
+#define fin2FeatureMask 0x08000000UL
+#define fin3FeatureMask 0x04000000UL
+#define med2FeatureMask 0x03000000UL /* two bits, from shifting either fin2 or fin3 */
+
+#define ccmpFeatureMask 0x00800000UL
+#define rligFeatureMask 0x00400000UL
+#define caltFeatureMask 0x00200000UL
+#define ligaFeatureMask 0x00100000UL
+#define dligFeatureMask 0x00080000UL
+#define cswhFeatureMask 0x00040000UL
+#define msetFeatureMask 0x00020000UL
+#define cursFeatureMask 0x00010000UL
+#define kernFeatureMask 0x00008000UL
+#define markFeatureMask 0x00004000UL
+#define mkmkFeatureMask 0x00002000UL
#define NO_FEATURES 0
#define ISOL_FEATURES (isolFeatureMask | ligaFeatureMask | msetFeatureMask | markFeatureMask | ccmpFeatureMask | rligFeatureMask | caltFeatureMask | dligFeatureMask | cswhFeatureMask | cursFeatureMask | kernFeatureMask | mkmkFeatureMask)
-#define SHAPE_MASK 0xF0000000UL
+#define SHAPE_MASK 0xFF000000UL
static const FeatureMap featureMap[] = {
{ccmpFeatureTag, ccmpFeatureMask},
{isolFeatureTag, isolFeatureMask},
{finaFeatureTag, finaFeatureMask},
+ {fin2FeatureTag, fin2FeatureMask},
+ {fin3FeatureTag, fin3FeatureMask},
{mediFeatureTag, mediFeatureMask},
+ {med2FeatureTag, med2FeatureMask},
{initFeatureTag, initFeatureMask},
{rligFeatureTag, rligFeatureMask},
{caltFeatureTag, caltFeatureMask},
@@ -138,6 +185,14 @@
// shaper.shape(errout, 2) (isolate to initial, or final to medial)
// shaper.shape(out, 1) (isolate to final)
+ // special cases for Syriac ALAPH:
+ // final ALAPH is fin2 when effective right char shapes but does not cause left shaping, and is not DALATH/RISH
+ // final ALAPH is fin3 when effective right char is DALATH/RISH
+ // medial ALAPH is med2 when effective right char shapes but does not cause left shaping
+ // using one of:
+ // shaper.shape(out, 4) (isolate to fin2)
+ // shaper.shape(out, 5) (isolate to fin3)
+
ShapeType rightType = ST_NOSHAPE_NONE, leftType = ST_NOSHAPE_NONE;
LEErrorCode success = LE_NO_ERROR;
le_int32 i;
@@ -195,10 +250,17 @@
if (curShapes) {
adjustTags(out, 1, glyphStorage);
}
+ } else if (t == ST_ALAPH) {
+ if (rightType == ST_DALATH_RISH) {
+ adjustTags(out, 5, glyphStorage);
+ } else if (rightShapes && !rightCauses) {
+ adjustTags(out, 4, glyphStorage);
+ }
}
rightShapes = curShapes;
rightCauses = (t & MASK_SHAPE_LEFT) != 0;
+ rightType = t; // remember this; might need to know if it was DALATH/RISH
erout = out;
}
diff -ur icu-49.1.orig/source/layout/ArabicShaping.h icu-49.1/source/layout/ArabicShaping.h
--- icu-49.1.orig/source/layout/ArabicShaping.h 2012-03-21 18:38:08.000000000 +0100
+++ icu-49.1/source/layout/ArabicShaping.h 2012-03-22 10:21:21.000000000 +0100
@@ -39,7 +39,10 @@
MASK_SHAPE_RIGHT = 1, // if this bit set, shapes to right
MASK_SHAPE_LEFT = 2, // if this bit set, shapes to left
MASK_TRANSPARENT = 4, // if this bit set, is transparent (ignore other bits)
- MASK_NOSHAPE = 8 // if this bit set, don't shape this char, i.e. tatweel
+ MASK_NOSHAPE = 8, // if this bit set, don't shape this char, i.e. tatweel
+
+ MASK_ALAPH = 16, // if this bit set, char is Syriac ALAPH
+ MASK_DALATH_RISH = 32 // if this bit set, char is Syriac DALATH/RISH
};
// shaping values
@@ -51,7 +54,9 @@
ST_DUAL = MASK_SHAPE_RIGHT | MASK_SHAPE_LEFT,
ST_TRANSPARENT = MASK_TRANSPARENT,
ST_NOSHAPE_DUAL = MASK_NOSHAPE | ST_DUAL,
- ST_NOSHAPE_NONE = MASK_NOSHAPE
+ ST_NOSHAPE_NONE = MASK_NOSHAPE,
+ ST_ALAPH = MASK_ALAPH | MASK_SHAPE_RIGHT,
+ ST_DALATH_RISH = MASK_DALATH_RISH | MASK_SHAPE_RIGHT
};
typedef le_int32 ShapeType;
@@ -69,6 +74,7 @@
static const le_uint8 shapingTypeTable[];
static const ShapeType shapeTypes[];
+ static const ShapeType mongolianTypes[];
static void adjustTags(le_int32 outIndex, le_int32 shapeOffset, LEGlyphStorage &glyphStorage);
};
diff -ur icu-49.1.orig/source/layout/LayoutEngine.cpp icu-49.1/source/layout/LayoutEngine.cpp
--- icu-49.1.orig/source/layout/LayoutEngine.cpp 2012-03-22 10:20:24.000000000 +0100
+++ icu-49.1/source/layout/LayoutEngine.cpp 2012-03-22 10:21:21.000000000 +0100
@@ -567,6 +567,8 @@
break;
case arabScriptCode:
+ case syrcScriptCode:
+ case mongScriptCode:
result = new ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success);
break;
|