]>
git.saurik.com Git - apple/icu.git/blob - icuSources/layout/ArabicShaping.cpp
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
);