]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/layout/ArabicShaping.cpp
ICU-8.11.tar.gz
[apple/icu.git] / icuSources / layout / ArabicShaping.cpp
index c26bb57eceff8654d724362d3614192e8a6be8dd..f8692ed10b928c86ae48d09383b25bdc71e6083c 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *
- * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
  *
  */
 
@@ -8,35 +8,20 @@
 #include "OpenTypeTables.h"
 #include "ArabicShaping.h"
 #include "LEGlyphStorage.h"
+#include "ClassDefinitionTables.h"
 
 U_NAMESPACE_BEGIN
 
-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
-};
-
+// This table maps Unicode joining types to
+// ShapeTypes.
 const ArabicShaping::ShapeType ArabicShaping::shapeTypes[] =
 {
-    _t_, _t_, _t_, _t_, _t_, _t_, _x_, _x_, _x_, _x_, _x_, _n_, _x_, _x_, _x_, _n_,   // 0x610 - 0x61f
-    _x_, _n_, _r_, _r_, _r_, _r_, _d_, _r_, _d_, _r_, _d_, _d_, _d_, _d_, _d_, _r_,   // 0x620 - 0x62f
-    _r_, _r_, _r_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _x_, _x_, _x_, _x_, _x_,   // 0x630 - 0x63f
-    _c_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _r_, _d_, _d_, _t_, _t_, _t_, _t_, _t_,   // 0x640 - 0x64f
-    _t_, _t_, _t_, _t_, _t_, _t_, _t_, _t_, _t_, _x_, _x_, _x_, _x_, _x_, _x_, _x_,   // 0x650 - 0x65f
-    _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _d_, _d_,   // 0x660 - 0x66f
-    _t_, _r_, _r_, _r_, _n_, _r_, _r_, _r_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_,   // 0x670 - 0x67f
-    _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _r_, _r_, _r_, _r_, _r_, _r_, _r_, _r_,   // 0x680 - 0x68f
-    _r_, _r_, _r_, _r_, _r_, _r_, _r_, _r_, _r_, _r_, _d_, _d_, _d_, _d_, _d_, _d_,   // 0x690 - 0x69f
-    _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_,   // 0x6a0 - 0x6af
-    _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_, _d_,   // 0x6b0 - 0x6bf
-    _r_, _d_, _r_, _r_, _r_, _r_, _r_, _r_, _r_, _r_, _r_, _r_, _d_, _r_, _d_, _r_,   // 0x6c0 - 0x6cf
-    _d_, _d_, _r_, _r_, _n_, _r_, _t_, _t_, _t_, _t_, _t_, _t_, _t_, _x_, _t_, _t_,   // 0x6d0 - 0x6df
-    _t_, _t_, _t_, _t_, _t_, _n_, _n_, _t_, _t_, _n_, _t_, _t_, _t_, _t_, _r_, _r_,   // 0x6e0 - 0x6ef
-    _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _n_, _d_, _d_, _d_, _n_, _n_, _d_    // 0x6f0 - 0x6ff
+    ArabicShaping::ST_NOSHAPE_NONE, // [U]
+    ArabicShaping::ST_NOSHAPE_DUAL, // [C]
+    ArabicShaping::ST_DUAL,         // [D]
+    ArabicShaping::ST_LEFT,         // [L]
+    ArabicShaping::ST_RIGHT,        // [R]
+    ArabicShaping::ST_TRANSPARENT   // [T]
 };
 
 /*
@@ -48,76 +33,90 @@ const ArabicShaping::ShapeType ArabicShaping::shapeTypes[] =
 */
 ArabicShaping::ShapeType ArabicShaping::getShapeType(LEUnicode c)
 {
-    if (c >= 0x0610 && c <= 0x206f) {
-        if (c < 0x0700) {
-            return shapeTypes[c - 0x0610];
-        } else if (c == 0x200c) {   // ZWNJ
-            return ST_NOSHAPE_NONE;
-        } else if (c == 0x200d) {   // ZWJ
-            return ST_NOSHAPE_DUAL;
-        } else if (c >= 0x202a && c <= 0x202e) { // LRE - RLO
-            return ST_TRANSPARENT;
-        } else if (c >= 0x206a && c <= 0x206f) { // Inhibit Symmetric Swapping - Nominal Digit Shapes
-            return ST_TRANSPARENT;
-        }
+    const ClassDefinitionTable *joiningTypes = (const ClassDefinitionTable *) ArabicShaping::shapingTypeTable;
+    le_int32 joiningType = joiningTypes->getGlyphClass(c);
+
+    if (joiningType >= 0 && joiningType < ArabicShaping::JT_COUNT) {
+        return ArabicShaping::shapeTypes[joiningType];
     }
 
-    return ST_NOSHAPE_NONE;
+    return ArabicShaping::ST_NOSHAPE_NONE;
 }
 
-static const LETag isolFeatureTag = LE_ISOL_FEATURE_TAG;
-static const LETag initFeatureTag = LE_INIT_FEATURE_TAG;
-static const LETag mediFeatureTag = LE_MEDI_FEATURE_TAG;
-static const LETag finaFeatureTag = LE_FINA_FEATURE_TAG;
-static const LETag ligaFeatureTag = LE_LIGA_FEATURE_TAG;
-static const LETag msetFeatureTag = LE_MSET_FEATURE_TAG;
-static const LETag markFeatureTag = LE_MARK_FEATURE_TAG;
-static const LETag ccmpFeatureTag = LE_CCMP_FEATURE_TAG;
-static const LETag rligFeatureTag = LE_RLIG_FEATURE_TAG;
-static const LETag caltFeatureTag = LE_CALT_FEATURE_TAG;
-static const LETag dligFeatureTag = LE_DLIG_FEATURE_TAG;
-static const LETag cswhFeatureTag = LE_CSWH_FEATURE_TAG;
-static const LETag cursFeatureTag = LE_CURS_FEATURE_TAG;
-static const LETag kernFeatureTag = LE_KERN_FEATURE_TAG;
-static const LETag mkmkFeatureTag = LE_MKMK_FEATURE_TAG;
-
-static const LETag emptyTag       = 0x00000000; // ''
-
-static const LETag featureOrder[] = 
-{
-    ccmpFeatureTag, isolFeatureTag, finaFeatureTag, mediFeatureTag, initFeatureTag, rligFeatureTag,
-    caltFeatureTag, ligaFeatureTag, dligFeatureTag, cswhFeatureTag, msetFeatureTag, cursFeatureTag,
-    kernFeatureTag, markFeatureTag, mkmkFeatureTag, emptyTag
+#define isolFeatureTag LE_ISOL_FEATURE_TAG
+#define initFeatureTag LE_INIT_FEATURE_TAG
+#define mediFeatureTag LE_MEDI_FEATURE_TAG
+#define finaFeatureTag LE_FINA_FEATURE_TAG
+#define ligaFeatureTag LE_LIGA_FEATURE_TAG
+#define msetFeatureTag LE_MSET_FEATURE_TAG
+#define markFeatureTag LE_MARK_FEATURE_TAG
+#define ccmpFeatureTag LE_CCMP_FEATURE_TAG
+#define rligFeatureTag LE_RLIG_FEATURE_TAG
+#define caltFeatureTag LE_CALT_FEATURE_TAG
+#define dligFeatureTag LE_DLIG_FEATURE_TAG
+#define cswhFeatureTag LE_CSWH_FEATURE_TAG
+#define cursFeatureTag LE_CURS_FEATURE_TAG
+#define kernFeatureTag LE_KERN_FEATURE_TAG
+#define mkmkFeatureTag LE_MKMK_FEATURE_TAG
+
+// 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.
+#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 ISOL_FEATURES (isolFeatureMask | ligaFeatureMask | msetFeatureMask | markFeatureMask | ccmpFeatureMask | rligFeatureMask | caltFeatureMask | dligFeatureMask | cswhFeatureMask | cursFeatureMask | kernFeatureMask | mkmkFeatureMask)
+
+#define SHAPE_MASK 0xF0000000UL
+
+static const FeatureMap featureMap[] = {
+    {ccmpFeatureTag, ccmpFeatureMask},
+    {isolFeatureTag, isolFeatureMask},
+    {finaFeatureTag, finaFeatureMask},
+    {mediFeatureTag, mediFeatureMask},
+    {initFeatureTag, initFeatureMask},
+    {rligFeatureTag, rligFeatureMask},
+    {caltFeatureTag, caltFeatureMask},
+    {ligaFeatureTag, ligaFeatureMask},
+    {dligFeatureTag, dligFeatureMask},
+    {cswhFeatureTag, cswhFeatureMask},
+    {msetFeatureTag, msetFeatureMask},
+    {cursFeatureTag, cursFeatureMask},
+    {kernFeatureTag, kernFeatureMask},
+    {markFeatureTag, markFeatureMask},
+    {mkmkFeatureTag, mkmkFeatureMask}
 };
 
-const LETag ArabicShaping::tagArray[] =
+const FeatureMap *ArabicShaping::getFeatureMap(le_int32 &count)
 {
-    isolFeatureTag, ligaFeatureTag, msetFeatureTag, markFeatureTag, ccmpFeatureTag, rligFeatureTag,
-        caltFeatureTag, dligFeatureTag, cswhFeatureTag, cursFeatureTag, kernFeatureTag, mkmkFeatureTag, emptyTag,
-
-    finaFeatureTag, ligaFeatureTag, msetFeatureTag, markFeatureTag, ccmpFeatureTag, rligFeatureTag,
-        caltFeatureTag, dligFeatureTag, cswhFeatureTag, cursFeatureTag, kernFeatureTag, mkmkFeatureTag, emptyTag,
+    count = LE_ARRAY_SIZE(featureMap);
 
-    initFeatureTag, ligaFeatureTag, msetFeatureTag, markFeatureTag, ccmpFeatureTag, rligFeatureTag,
-        caltFeatureTag, dligFeatureTag, cswhFeatureTag, cursFeatureTag, kernFeatureTag, mkmkFeatureTag, emptyTag,
-
-    mediFeatureTag, ligaFeatureTag, msetFeatureTag, markFeatureTag, ccmpFeatureTag, rligFeatureTag,
-        caltFeatureTag, dligFeatureTag, cswhFeatureTag, cursFeatureTag, kernFeatureTag, mkmkFeatureTag, emptyTag
-};
-
-#define TAGS_PER_GLYPH ((sizeof ArabicShaping::tagArray / sizeof ArabicShaping::tagArray[0]) / 4)
-
-const LETag *ArabicShaping::getFeatureOrder()
-{
-    return featureOrder;
+    return featureMap;
 }
 
 void ArabicShaping::adjustTags(le_int32 outIndex, le_int32 shapeOffset, LEGlyphStorage &glyphStorage)
 {
     LEErrorCode success = LE_NO_ERROR;
-    const LETag *glyphTags = (const LETag *) glyphStorage.getAuxData(outIndex, success);
+    FeatureMask featureMask = (FeatureMask) glyphStorage.getAuxData(outIndex, success);
+    FeatureMask shape = featureMask & SHAPE_MASK;
+
+    shape >>= shapeOffset;
 
-    glyphStorage.setAuxData(outIndex, (void *) &glyphTags[TAGS_PER_GLYPH * shapeOffset], success);
+    glyphStorage.setAuxData(outIndex, ((featureMask & ~SHAPE_MASK) | shape), success);
 }
 
 void ArabicShaping::shape(const LEUnicode *chars, le_int32 offset, le_int32 charCount, le_int32 charMax,
@@ -174,7 +173,7 @@ void ArabicShaping::shape(const LEUnicode *chars, le_int32 offset, le_int32 char
         LEUnicode c = chars[in];
         ShapeType t = getShapeType(c);
 
-        glyphStorage.setAuxData(out, (void *) tagArray, success);
+        glyphStorage.setAuxData(out, ISOL_FEATURES, success);
 
         if ((t & MASK_TRANSPARENT) != 0) {
             continue;