os/textandloc/fontservices/textshaperplugin/IcuSource/layout/ArabicLayoutEngine.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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