fontservices/textshaperplugin/IcuSource/layout/ArabicLayoutEngine.cpp
changeset 0 1fb32624e06b
equal deleted inserted replaced
-1:000000000000 0:1fb32624e06b
       
     1 
       
     2 /*
       
     3  *
       
     4  * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
       
     5  *
       
     6  */
       
     7 
       
     8 #include "LETypes.h"
       
     9 #include "LEScripts.h"
       
    10 #include "LEGlyphFilter.h"
       
    11 #include "LEGlyphStorage.h"
       
    12 #include "LayoutEngine.h"
       
    13 #include "OpenTypeLayoutEngine.h"
       
    14 #include "ArabicLayoutEngine.h"
       
    15 #include "ScriptAndLanguageTags.h"
       
    16 #include "CharSubstitutionFilter.h"
       
    17 
       
    18 #include "GlyphSubstitutionTables.h"
       
    19 #include "GlyphDefinitionTables.h"
       
    20 #include "GlyphPositioningTables.h"
       
    21 
       
    22 #include "GDEFMarkFilter.h"
       
    23 
       
    24 #include "ArabicShaping.h"
       
    25 #include "CanonShaping.h"
       
    26 
       
    27 U_NAMESPACE_BEGIN
       
    28 
       
    29 le_bool CharSubstitutionFilter::accept(LEGlyphID glyph) const
       
    30 {
       
    31     return fFontInstance->canDisplay((LEUnicode) glyph);
       
    32 }
       
    33 
       
    34 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ArabicOpenTypeLayoutEngine)
       
    35 
       
    36 ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
       
    37                         le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable)
       
    38     : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable)
       
    39 {
       
    40     /**/ fFeatureOrder = ArabicShaping::getFeatureOrder();
       
    41 }
       
    42 
       
    43 ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
       
    44 						       le_int32 typoFlags)
       
    45     : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags)
       
    46 {
       
    47     // fFeatureOrder = ArabicShaping::getFeatureOrder();
       
    48 }
       
    49 
       
    50 ArabicOpenTypeLayoutEngine::~ArabicOpenTypeLayoutEngine()
       
    51 {
       
    52     // nothing to do
       
    53 }
       
    54 
       
    55 // Input: characters
       
    56 // Output: characters, char indices, tags
       
    57 // Returns: output character count
       
    58 le_int32 ArabicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
       
    59         LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success)
       
    60 {
       
    61     if (LE_FAILURE(success)) {
       
    62         return 0;
       
    63     }
       
    64 
       
    65     if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) {
       
    66         success = LE_ILLEGAL_ARGUMENT_ERROR;
       
    67         return 0;
       
    68     }
       
    69 
       
    70     outChars = LE_NEW_ARRAY(LEUnicode, count);
       
    71 
       
    72     if (outChars == NULL) {
       
    73         success = LE_MEMORY_ALLOCATION_ERROR;
       
    74         return 0;
       
    75     }
       
    76 
       
    77     glyphStorage.allocateGlyphArray(count, rightToLeft, success);
       
    78     glyphStorage.allocateAuxData(success);
       
    79 
       
    80     if (LE_FAILURE(success)) {
       
    81         LE_DELETE_ARRAY(outChars);
       
    82         return 0;
       
    83     }
       
    84 
       
    85     CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, outChars, glyphStorage);
       
    86 
       
    87     // Note: This processes the *original* character array so we can get context
       
    88     // for the first and last characters. This is OK because only the marks
       
    89     // will have been reordered, and they don't contribute to shaping.
       
    90     ArabicShaping::shape(chars, offset, count, max, rightToLeft, glyphStorage);
       
    91 
       
    92     return count;
       
    93 }
       
    94 
       
    95 void ArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse,
       
    96                                                       LEGlyphStorage &glyphStorage, LEErrorCode &success)
       
    97 {
       
    98     if (LE_FAILURE(success)) {
       
    99         return;
       
   100     }
       
   101 
       
   102     if (chars == NULL || offset < 0 || count < 0) {
       
   103         success = LE_ILLEGAL_ARGUMENT_ERROR;
       
   104         return;
       
   105     }
       
   106 
       
   107     if (fGPOSTable != NULL) {
       
   108         OpenTypeLayoutEngine::adjustGlyphPositions(chars, offset, count, reverse, glyphStorage, success);
       
   109     } else if (fGDEFTable != NULL) {
       
   110         GDEFMarkFilter filter(fGDEFTable);
       
   111 
       
   112         adjustMarkGlyphs(glyphStorage, &filter, success);
       
   113     } else {
       
   114         GlyphDefinitionTableHeader *gdefTable = (GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable;
       
   115         GDEFMarkFilter filter(gdefTable);
       
   116 
       
   117         adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
       
   118     }
       
   119 }
       
   120 
       
   121 UnicodeArabicOpenTypeLayoutEngine::UnicodeArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags)
       
   122     : ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags)
       
   123 {
       
   124     fGSUBTable = (const GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable;
       
   125     fGDEFTable = (const GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable;
       
   126 
       
   127     fSubstitutionFilter = new CharSubstitutionFilter(fontInstance);
       
   128 }
       
   129 
       
   130 UnicodeArabicOpenTypeLayoutEngine::~UnicodeArabicOpenTypeLayoutEngine()
       
   131 {
       
   132     delete fSubstitutionFilter;
       
   133 }
       
   134 
       
   135 // "glyphs", "indices" -> glyphs, indices
       
   136 le_int32 UnicodeArabicOpenTypeLayoutEngine::glyphPostProcessing(LEGlyphStorage &tempGlyphStorage, LEGlyphStorage &glyphStorage, LEErrorCode &success)
       
   137 {
       
   138     if (LE_FAILURE(success)) {
       
   139         return 0;
       
   140     }
       
   141 
       
   142     // FIXME: we could avoid the memory allocation and copy if we
       
   143     // made a clone of mapCharsToGlyphs which took the fake glyphs
       
   144     // directly.
       
   145     le_int32 tempGlyphCount = tempGlyphStorage.getGlyphCount();
       
   146     LEUnicode *tempChars = LE_NEW_ARRAY(LEUnicode, tempGlyphCount);
       
   147 
       
   148     if (tempChars == NULL) {
       
   149         success = LE_MEMORY_ALLOCATION_ERROR;
       
   150         return 0;
       
   151     }
       
   152 
       
   153     for (le_int32 i = 0; i < tempGlyphCount; i += 1) {
       
   154         tempChars[i] = (LEUnicode) LE_GET_GLYPH(tempGlyphStorage[i]);
       
   155     }
       
   156 
       
   157     glyphStorage.adoptCharIndicesArray(tempGlyphStorage);
       
   158 
       
   159     ArabicOpenTypeLayoutEngine::mapCharsToGlyphs(tempChars, 0, tempGlyphCount, FALSE, TRUE, glyphStorage, success);
       
   160 
       
   161     LE_DELETE_ARRAY(tempChars);
       
   162 
       
   163     return tempGlyphCount;
       
   164 }
       
   165 
       
   166 void UnicodeArabicOpenTypeLayoutEngine::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool /*mirror*/, LEGlyphStorage &glyphStorage, LEErrorCode &success)
       
   167 {
       
   168     if (LE_FAILURE(success)) {
       
   169         return;
       
   170     }
       
   171 
       
   172     if (chars == NULL || offset < 0 || count < 0) {
       
   173         success = LE_ILLEGAL_ARGUMENT_ERROR;
       
   174         return;
       
   175     }
       
   176 
       
   177     le_int32 i, dir = 1, out = 0;
       
   178 
       
   179     if (reverse) {
       
   180         out = count - 1;
       
   181         dir = -1;
       
   182     }
       
   183 
       
   184     glyphStorage.allocateGlyphArray(count, reverse, success);
       
   185 
       
   186     for (i = 0; i < count; i += 1, out += dir) {
       
   187         glyphStorage[out] = (LEGlyphID) chars[offset + i];
       
   188     }
       
   189 }
       
   190 
       
   191 void UnicodeArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse,
       
   192                                                       LEGlyphStorage &glyphStorage, LEErrorCode &success)
       
   193 {
       
   194     if (LE_FAILURE(success)) {
       
   195         return;
       
   196     }
       
   197 
       
   198     if (chars == NULL || offset < 0 || count < 0) {
       
   199         success = LE_ILLEGAL_ARGUMENT_ERROR;
       
   200         return;
       
   201     }
       
   202 
       
   203     GDEFMarkFilter filter(fGDEFTable);
       
   204 
       
   205     adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
       
   206 }
       
   207 
       
   208 U_NAMESPACE_END
       
   209