]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/layout/OpenTypeLayoutEngine.cpp
ICU-400.37.tar.gz
[apple/icu.git] / icuSources / layout / OpenTypeLayoutEngine.cpp
index fbbfc0e68462cea85383201671a85b05f5610129..c08eb69cb679cf04898b7b6ae261f8ed399f10d2 100644 (file)
@@ -1,7 +1,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 1998-2006 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
  *
  */
 
@@ -10,6 +10,7 @@
 #include "LELanguages.h"
 
 #include "LayoutEngine.h"
+#include "CanonShaping.h"
 #include "OpenTypeLayoutEngine.h"
 #include "ScriptAndLanguageTags.h"
 #include "CharSubstitutionFilter.h"
@@ -33,6 +34,7 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(OpenTypeLayoutEngine)
 #define kernFeatureTag LE_KERN_FEATURE_TAG
 #define markFeatureTag LE_MARK_FEATURE_TAG
 #define mkmkFeatureTag LE_MKMK_FEATURE_TAG
+#define loclFeatureTag LE_LOCL_FEATURE_TAG
 
 // 'dlig' not used at the moment
 #define dligFeatureTag 0x646C6967
@@ -47,8 +49,9 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(OpenTypeLayoutEngine)
 #define paltFeatureMask 0x08000000UL
 #define markFeatureMask 0x04000000UL
 #define mkmkFeatureMask 0x02000000UL
+#define loclFeatureMask 0x01000000UL
 
-#define minimalFeatures     (ccmpFeatureMask | markFeatureMask | mkmkFeatureMask)
+#define minimalFeatures     (ccmpFeatureMask | markFeatureMask | mkmkFeatureMask | loclFeatureMask)
 #define ligaFeatures        (ligaFeatureMask | cligFeatureMask | minimalFeatures)
 #define kernFeatures        (kernFeatureMask | paltFeatureMask | minimalFeatures)
 #define kernAndLigaFeatures (ligaFeatures    | kernFeatures)
@@ -58,10 +61,11 @@ static const FeatureMap featureMap[] =
     {ccmpFeatureTag, ccmpFeatureMask},
     {ligaFeatureTag, ligaFeatureMask},
     {cligFeatureTag, cligFeatureMask}, 
-       {kernFeatureTag, kernFeatureMask},
+    {kernFeatureTag, kernFeatureMask},
     {paltFeatureTag, paltFeatureMask},
     {markFeatureTag, markFeatureMask},
-    {mkmkFeatureTag, mkmkFeatureMask}
+    {mkmkFeatureTag, mkmkFeatureMask},
+    {loclFeatureTag, loclFeatureMask}
 };
 
 static const le_int32 featureMapCount = LE_ARRAY_SIZE(featureMap);
@@ -70,7 +74,7 @@ OpenTypeLayoutEngine::OpenTypeLayoutEngine(const LEFontInstance *fontInstance, l
                         le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable)
     : LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags), fFeatureMask(minimalFeatures),
       fFeatureMap(featureMap), fFeatureMapCount(featureMapCount), fFeatureOrder(FALSE),
-      fGSUBTable(gsubTable), fGDEFTable(NULL), fGPOSTable(NULL), fSubstitutionFilter(NULL), fFilterZeroWidth(TRUE)
+      fGSUBTable(gsubTable), fGDEFTable(NULL), fGPOSTable(NULL), fSubstitutionFilter(NULL)
 {
     static const le_uint32 gdefTableTag = LE_GDEF_TABLE_TAG;
     static const le_uint32 gposTableTag = LE_GPOS_TABLE_TAG;
@@ -108,9 +112,9 @@ void OpenTypeLayoutEngine::reset()
 }
 
 OpenTypeLayoutEngine::OpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
-                                          le_int32 typoFlags)
+                       le_int32 typoFlags)
     : LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags), fFeatureOrder(FALSE),
-      fGSUBTable(NULL), fGDEFTable(NULL), fGPOSTable(NULL), fSubstitutionFilter(NULL), fFilterZeroWidth(TRUE)
+      fGSUBTable(NULL), fGDEFTable(NULL), fGPOSTable(NULL), fSubstitutionFilter(NULL)
 {
     setScriptAndLanguageTags();
 }
@@ -160,20 +164,30 @@ le_int32 OpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_i
         return 0;
     }
 
-    le_int32 outCharCount = LayoutEngine::characterProcessing(chars, offset, count, max, rightToLeft, outChars, glyphStorage, success);
+    // This is the cheapest way to get mark reordering only for Hebrew.
+    // We could just do the mark reordering for all scripts, but most
+    // of them probably don't need it... Another option would be to
+    // add a HebrewOpenTypeLayoutEngine subclass, but the only thing it
+    // would need to do is mark reordering, so that seems like overkill.
+    if (fScriptCode == hebrScriptCode) {
+        outChars = LE_NEW_ARRAY(LEUnicode, count);
 
-    if (LE_FAILURE(success)) {
-        return 0;
+        if (outChars == NULL) {
+            success = LE_MEMORY_ALLOCATION_ERROR;
+            return 0;
+        }
+
+        CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, outChars, glyphStorage);
     }
 
-    glyphStorage.allocateGlyphArray(outCharCount, rightToLeft, success);
+    glyphStorage.allocateGlyphArray(count, rightToLeft, success);
     glyphStorage.allocateAuxData(success);
 
-    for (le_int32 i = 0; i < outCharCount; i += 1) {
+    for (le_int32 i = 0; i < count; i += 1) {
         glyphStorage.setAuxData(i, fFeatureMask, success);
     }
 
-    return outCharCount;
+    return count;
 }
 
 // Input: characters, tags
@@ -190,7 +204,7 @@ le_int32 OpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_int32
         return 0;
     }
 
-    mapCharsToGlyphs(chars, offset, count, rightToLeft, rightToLeft, fFilterZeroWidth, glyphStorage, success);
+    mapCharsToGlyphs(chars, offset, count, rightToLeft, rightToLeft, glyphStorage, success);
 
     if (LE_FAILURE(success)) {
         return 0;
@@ -332,6 +346,18 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3
         delete adjustments;
     }
 
+    LEGlyphID zwnj  = fFontInstance->mapCharToGlyph(0x200C);
+
+    if (zwnj != 0x0000) {
+        for (le_int32 g = 0; g < glyphCount; g += 1) {
+            LEGlyphID glyph = glyphStorage[g];
+
+            if (glyph == zwnj) {
+                glyphStorage[g] = LE_SET_GLYPH(glyph, 0xFFFF);
+            }
+        }
+    }
+
 #if 0
     // Don't know why this is here...
     LE_DELETE_ARRAY(fFeatureTags);