Update contrib.
3 * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
8 #include "OpenTypeTables.h"
9 #include "ArabicShaping.h"
10 #include "LEGlyphStorage.h"
15 _c_ = ArabicShaping::ST_NOSHAPE_DUAL,
16 _d_ = ArabicShaping::ST_DUAL,
17 _n_ = ArabicShaping::ST_NONE,
18 _r_ = ArabicShaping::ST_RIGHT,
19 _t_ = ArabicShaping::ST_TRANSPARENT,
20 _x_ = ArabicShaping::ST_NOSHAPE_NONE
23 const ArabicShaping::ShapeType ArabicShaping::shapeTypes[] =
25 _t_, _t_, _t_, _t_, _t_, _t_, _x_, _x_, _x_, _x_, _x_, _n_, _x_, _x_, _x_, _n_, // 0x610 - 0x61f
26 _x_, _n_, _r_, _r_, _r_, _r_, _d_, _r_, _d_, _r_, _d_, _d_, _d_, _d_, _d_, _r_, // 0x620 - 0x62f
27 _r_, _r_, _r_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _x_, _x_, _x_, _x_, _x_, // 0x630 - 0x63f
28 _c_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _r_, _d_, _d_, _t_, _t_, _t_, _t_, _t_, // 0x640 - 0x64f
29 _t_, _t_, _t_, _t_, _t_, _t_, _t_, _t_, _t_, _x_, _x_, _x_, _x_, _x_, _x_, _x_, // 0x650 - 0x65f
30 _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _d_, _d_, // 0x660 - 0x66f
31 _t_, _r_, _r_, _r_, _n_, _r_, _r_, _r_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, // 0x670 - 0x67f
32 _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _r_, _r_, _r_, _r_, _r_, _r_, _r_, _r_, // 0x680 - 0x68f
33 _r_, _r_, _r_, _r_, _r_, _r_, _r_, _r_, _r_, _r_, _d_, _d_, _d_, _d_, _d_, _d_, // 0x690 - 0x69f
34 _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, // 0x6a0 - 0x6af
35 _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, // 0x6b0 - 0x6bf
36 _r_, _d_, _r_, _r_, _r_, _r_, _r_, _r_, _r_, _r_, _r_, _r_, _d_, _r_, _d_, _r_, // 0x6c0 - 0x6cf
37 _d_, _d_, _r_, _r_, _n_, _r_, _t_, _t_, _t_, _t_, _t_, _t_, _t_, _x_, _t_, _t_, // 0x6d0 - 0x6df
38 _t_, _t_, _t_, _t_, _t_, _n_, _n_, _t_, _t_, _n_, _t_, _t_, _t_, _t_, _r_, _r_, // 0x6e0 - 0x6ef
39 _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _d_, _d_, _d_, _n_, _n_, _d_ // 0x6f0 - 0x6ff
43 shaping array holds types for Arabic chars between 0610 and 0700
44 other values are either unshaped, or transparent if a mark or format
45 code, except for format codes 200c (zero-width non-joiner) and 200d
46 (dual-width joiner) which are both unshaped and non_joining or
47 dual-joining, respectively.
49 ArabicShaping::ShapeType ArabicShaping::getShapeType(LEUnicode c)
51 if (c >= 0x0610 && c <= 0x206f) {
53 return shapeTypes[c - 0x0610];
54 } else if (c == 0x200c) { // ZWNJ
55 return ST_NOSHAPE_NONE;
56 } else if (c == 0x200d) { // ZWJ
57 return ST_NOSHAPE_DUAL;
58 } else if (c >= 0x202a && c <= 0x202e) { // LRE - RLO
59 return ST_TRANSPARENT;
60 } else if (c >= 0x206a && c <= 0x206f) { // Inhibit Symmetric Swapping - Nominal Digit Shapes
61 return ST_TRANSPARENT;
65 return ST_NOSHAPE_NONE;
68 static const LETag isolFeatureTag = LE_ISOL_FEATURE_TAG;
69 static const LETag initFeatureTag = LE_INIT_FEATURE_TAG;
70 static const LETag mediFeatureTag = LE_MEDI_FEATURE_TAG;
71 static const LETag finaFeatureTag = LE_FINA_FEATURE_TAG;
72 static const LETag ligaFeatureTag = LE_LIGA_FEATURE_TAG;
73 static const LETag msetFeatureTag = LE_MSET_FEATURE_TAG;
74 static const LETag markFeatureTag = LE_MARK_FEATURE_TAG;
75 static const LETag ccmpFeatureTag = LE_CCMP_FEATURE_TAG;
76 static const LETag rligFeatureTag = LE_RLIG_FEATURE_TAG;
77 static const LETag caltFeatureTag = LE_CALT_FEATURE_TAG;
78 static const LETag dligFeatureTag = LE_DLIG_FEATURE_TAG;
79 static const LETag cswhFeatureTag = LE_CSWH_FEATURE_TAG;
80 static const LETag cursFeatureTag = LE_CURS_FEATURE_TAG;
81 static const LETag kernFeatureTag = LE_KERN_FEATURE_TAG;
82 static const LETag mkmkFeatureTag = LE_MKMK_FEATURE_TAG;
84 static const LETag emptyTag = 0x00000000; // ''
86 static const LETag featureOrder[] =
88 ccmpFeatureTag, isolFeatureTag, finaFeatureTag, mediFeatureTag, initFeatureTag, rligFeatureTag,
89 caltFeatureTag, ligaFeatureTag, dligFeatureTag, cswhFeatureTag, msetFeatureTag, cursFeatureTag,
90 kernFeatureTag, markFeatureTag, mkmkFeatureTag, emptyTag
93 const LETag ArabicShaping::tagArray[] =
95 isolFeatureTag, ligaFeatureTag, msetFeatureTag, markFeatureTag, ccmpFeatureTag, rligFeatureTag,
96 caltFeatureTag, dligFeatureTag, cswhFeatureTag, cursFeatureTag, kernFeatureTag, mkmkFeatureTag, emptyTag,
98 finaFeatureTag, ligaFeatureTag, msetFeatureTag, markFeatureTag, ccmpFeatureTag, rligFeatureTag,
99 caltFeatureTag, dligFeatureTag, cswhFeatureTag, cursFeatureTag, kernFeatureTag, mkmkFeatureTag, emptyTag,
101 initFeatureTag, ligaFeatureTag, msetFeatureTag, markFeatureTag, ccmpFeatureTag, rligFeatureTag,
102 caltFeatureTag, dligFeatureTag, cswhFeatureTag, cursFeatureTag, kernFeatureTag, mkmkFeatureTag, emptyTag,
104 mediFeatureTag, ligaFeatureTag, msetFeatureTag, markFeatureTag, ccmpFeatureTag, rligFeatureTag,
105 caltFeatureTag, dligFeatureTag, cswhFeatureTag, cursFeatureTag, kernFeatureTag, mkmkFeatureTag, emptyTag
108 #define TAGS_PER_GLYPH ((sizeof ArabicShaping::tagArray / sizeof ArabicShaping::tagArray[0]) / 4)
110 const LETag *ArabicShaping::getFeatureOrder()
115 void ArabicShaping::adjustTags(le_int32 outIndex, le_int32 shapeOffset, LEGlyphStorage &glyphStorage)
117 LEErrorCode success = LE_NO_ERROR;
118 const LETag *glyphTags = (const LETag *) glyphStorage.getAuxData(outIndex, success);
120 glyphStorage.setAuxData(outIndex, (void *) &glyphTags[TAGS_PER_GLYPH * shapeOffset], success);
123 void ArabicShaping::shape(const LEUnicode *chars, le_int32 offset, le_int32 charCount, le_int32 charMax,
124 le_bool rightToLeft, LEGlyphStorage &glyphStorage)
126 // iterate in logical order, store tags in visible order
128 // the effective right char is the most recently encountered
129 // non-transparent char
131 // four boolean states:
132 // the effective right char shapes
133 // the effective right char causes left shaping
134 // the current char shapes
135 // the current char causes right shaping
137 // if both cause shaping, then
138 // shaper.shape(errout, 2) (isolate to initial, or final to medial)
139 // shaper.shape(out, 1) (isolate to final)
141 ShapeType rightType = ST_NOSHAPE_NONE, leftType = ST_NOSHAPE_NONE;
142 LEErrorCode success = LE_NO_ERROR;
145 for (i = offset - 1; i >= 0; i -= 1) {
146 rightType = getShapeType(chars[i]);
148 if (rightType != ST_TRANSPARENT) {
153 for (i = offset + charCount; i < charMax; i += 1) {
154 leftType = getShapeType(chars[i]);
156 if (leftType != ST_TRANSPARENT) {
161 // erout is effective right logical index
163 le_bool rightShapes = FALSE;
164 le_bool rightCauses = (rightType & MASK_SHAPE_LEFT) != 0;
165 le_int32 in, e, out = 0, dir = 1;
173 for (in = offset, e = offset + charCount; in < e; in += 1, out += dir) {
174 LEUnicode c = chars[in];
175 ShapeType t = getShapeType(c);
177 glyphStorage.setAuxData(out, (void *) tagArray, success);
179 if ((t & MASK_TRANSPARENT) != 0) {
183 le_bool curShapes = (t & MASK_NOSHAPE) == 0;
184 le_bool curCauses = (t & MASK_SHAPE_RIGHT) != 0;
186 if (rightCauses && curCauses) {
188 adjustTags(erout, 2, glyphStorage);
192 adjustTags(out, 1, glyphStorage);
196 rightShapes = curShapes;
197 rightCauses = (t & MASK_SHAPE_LEFT) != 0;
201 if (rightShapes && rightCauses && (leftType & MASK_SHAPE_RIGHT) != 0) {
202 adjustTags(erout, 2, glyphStorage);