jdk/src/share/native/sun/font/layout/LayoutEngine.cpp
changeset 3935 afcdb712a9c5
parent 2 90ce3da70b43
child 5506 202f599c92aa
equal deleted inserted replaced
3933:38e8ef00316e 3935:afcdb712a9c5
    21  * CA 95054 USA or visit www.sun.com if you need additional information or
    21  * CA 95054 USA or visit www.sun.com if you need additional information or
    22  * have any questions.
    22  * have any questions.
    23  *
    23  *
    24  */
    24  */
    25 
    25 
       
    26 
    26 /*
    27 /*
    27  *
    28  *
    28  * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
    29  * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
    29  *
    30  *
    30  */
    31  */
    38 #include "CanonShaping.h"
    39 #include "CanonShaping.h"
    39 #include "HanLayoutEngine.h"
    40 #include "HanLayoutEngine.h"
    40 #include "IndicLayoutEngine.h"
    41 #include "IndicLayoutEngine.h"
    41 #include "KhmerLayoutEngine.h"
    42 #include "KhmerLayoutEngine.h"
    42 #include "ThaiLayoutEngine.h"
    43 #include "ThaiLayoutEngine.h"
       
    44 //#include "TibetanLayoutEngine.h"
    43 #include "GXLayoutEngine.h"
    45 #include "GXLayoutEngine.h"
    44 #include "ScriptAndLanguageTags.h"
    46 #include "ScriptAndLanguageTags.h"
    45 #include "CharSubstitutionFilter.h"
    47 #include "CharSubstitutionFilter.h"
    46 
    48 
    47 #include "LEGlyphStorage.h"
    49 #include "LEGlyphStorage.h"
    52 #include "MorphTables.h"
    54 #include "MorphTables.h"
    53 
    55 
    54 #include "DefaultCharMapper.h"
    56 #include "DefaultCharMapper.h"
    55 
    57 
    56 #include "KernTable.h"
    58 #include "KernTable.h"
       
    59 
       
    60 U_NAMESPACE_BEGIN
    57 
    61 
    58 const LEUnicode32 DefaultCharMapper::controlChars[] = {
    62 const LEUnicode32 DefaultCharMapper::controlChars[] = {
    59     0x0009, 0x000A, 0x000D,
    63     0x0009, 0x000A, 0x000D,
    60     /*0x200C, 0x200D,*/ 0x200E, 0x200F,
    64     /*0x200C, 0x200D,*/ 0x200E, 0x200F,
    61     0x2028, 0x2029, 0x202A, 0x202B, 0x202C, 0x202D, 0x202E,
    65     0x2028, 0x2029, 0x202A, 0x202B, 0x202C, 0x202D, 0x202E,
    99             return 0xFFFF;
   103             return 0xFFFF;
   100         }
   104         }
   101     }
   105     }
   102 
   106 
   103     if (fMirror) {
   107     if (fMirror) {
   104         le_int32 index = OpenTypeUtilities::search((le_uint32) ch,
   108         le_int32 index = OpenTypeUtilities::search((le_uint32) ch, (le_uint32 *)DefaultCharMapper::mirroredChars, DefaultCharMapper::mirroredCharsCount);
   105                                                    (le_uint32 *)DefaultCharMapper::mirroredChars,
       
   106                                                    DefaultCharMapper::mirroredCharsCount);
       
   107 
   109 
   108         if (mirroredChars[index] == ch) {
   110         if (mirroredChars[index] == ch) {
   109             return DefaultCharMapper::srahCderorrim[index];
   111             return DefaultCharMapper::srahCderorrim[index];
   110         }
   112         }
   111     }
   113     }
   130 CharSubstitutionFilter::~CharSubstitutionFilter()
   132 CharSubstitutionFilter::~CharSubstitutionFilter()
   131 {
   133 {
   132     // nothing to do
   134     // nothing to do
   133 }
   135 }
   134 
   136 
       
   137 
       
   138 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LayoutEngine)
       
   139 
   135 #define ccmpFeatureTag  LE_CCMP_FEATURE_TAG
   140 #define ccmpFeatureTag  LE_CCMP_FEATURE_TAG
   136 
   141 
   137 #define ccmpFeatureMask 0x80000000UL
   142 #define ccmpFeatureMask 0x80000000UL
   138 
   143 
   139 #define canonFeatures (ccmpFeatureMask)
   144 #define canonFeatures (ccmpFeatureMask)
   143     {ccmpFeatureTag, ccmpFeatureMask}
   148     {ccmpFeatureTag, ccmpFeatureMask}
   144 };
   149 };
   145 
   150 
   146 static const le_int32 canonFeatureMapCount = LE_ARRAY_SIZE(canonFeatureMap);
   151 static const le_int32 canonFeatureMapCount = LE_ARRAY_SIZE(canonFeatureMap);
   147 
   152 
   148 LayoutEngine::LayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode,
   153 LayoutEngine::LayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags)
   149     le_int32 languageCode, le_int32 typoFlags)
   154   : fGlyphStorage(NULL), fFontInstance(fontInstance), fScriptCode(scriptCode), fLanguageCode(languageCode),
   150   : fGlyphStorage(NULL), fFontInstance(fontInstance), fScriptCode(scriptCode),
   155     fTypoFlags(typoFlags)
   151     fLanguageCode(languageCode), fTypoFlags(typoFlags)
       
   152 {
   156 {
   153     fGlyphStorage = new LEGlyphStorage();
   157     fGlyphStorage = new LEGlyphStorage();
   154 }
   158 }
   155 
   159 
   156 le_int32 LayoutEngine::getGlyphCount() const
   160 le_int32 LayoutEngine::getGlyphCount() const
   157 {
   161 {
   158     return fGlyphStorage->getGlyphCount();
   162     return fGlyphStorage->getGlyphCount();
   159 }
   163 }
   160 
   164 
   161 void LayoutEngine::getCharIndices(le_int32 charIndices[], le_int32 indexBase,
   165 void LayoutEngine::getCharIndices(le_int32 charIndices[], le_int32 indexBase, LEErrorCode &success) const
   162     LEErrorCode &success) const
       
   163 {
   166 {
   164     fGlyphStorage->getCharIndices(charIndices, indexBase, success);
   167     fGlyphStorage->getCharIndices(charIndices, indexBase, success);
   165 }
   168 }
   166 
   169 
   167 void LayoutEngine::getCharIndices(le_int32 charIndices[], LEErrorCode &success) const
   170 void LayoutEngine::getCharIndices(le_int32 charIndices[], LEErrorCode &success) const
   168 {
   171 {
   169     fGlyphStorage->getCharIndices(charIndices, success);
   172     fGlyphStorage->getCharIndices(charIndices, success);
   170 }
   173 }
   171 
   174 
   172 // Copy the glyphs into caller's (32-bit) glyph array, OR in extraBits
   175 // Copy the glyphs into caller's (32-bit) glyph array, OR in extraBits
   173 void LayoutEngine::getGlyphs(le_uint32 glyphs[], le_uint32 extraBits,
   176 void LayoutEngine::getGlyphs(le_uint32 glyphs[], le_uint32 extraBits, LEErrorCode &success) const
   174     LEErrorCode &success) const
       
   175 {
   177 {
   176     fGlyphStorage->getGlyphs(glyphs, extraBits, success);
   178     fGlyphStorage->getGlyphs(glyphs, extraBits, success);
   177 }
   179 }
   178 
   180 
   179 void LayoutEngine::getGlyphs(LEGlyphID glyphs[], LEErrorCode &success) const
   181 void LayoutEngine::getGlyphs(LEGlyphID glyphs[], LEErrorCode &success) const
   216 void LayoutEngine::getGlyphPositions(float positions[], LEErrorCode &success) const
   218 void LayoutEngine::getGlyphPositions(float positions[], LEErrorCode &success) const
   217 {
   219 {
   218     fGlyphStorage->getGlyphPositions(positions, success);
   220     fGlyphStorage->getGlyphPositions(positions, success);
   219 }
   221 }
   220 
   222 
   221 void LayoutEngine::getGlyphPosition(le_int32 glyphIndex, float &x, float &y,
   223 void LayoutEngine::getGlyphPosition(le_int32 glyphIndex, float &x, float &y, LEErrorCode &success) const
   222     LEErrorCode &success) const
       
   223 {
   224 {
   224     fGlyphStorage->getGlyphPosition(glyphIndex, x, y, success);
   225     fGlyphStorage->getGlyphPosition(glyphIndex, x, y, success);
   225 }
   226 }
   226 
   227 
   227 le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset,
   228 le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
   228     le_int32 count, le_int32 max, le_bool rightToLeft, LEUnicode *&outChars,
   229                 LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success)
   229     LEGlyphStorage &glyphStorage, LEErrorCode &success)
       
   230 {
   230 {
   231     if (LE_FAILURE(success)) {
   231     if (LE_FAILURE(success)) {
   232         return 0;
   232         return 0;
   233     }
   233     }
   234 
   234 
   235     if (offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) {
   235     if (offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) {
   236         success = LE_ILLEGAL_ARGUMENT_ERROR;
   236         success = LE_ILLEGAL_ARGUMENT_ERROR;
   237         return 0;
   237         return 0;
   238     }
   238     }
   239 
   239 
   240     if ((fTypoFlags & 0x4) == 0) { // no canonical processing
   240     const GlyphSubstitutionTableHeader *canonGSUBTable = (GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable;
   241         return count;
       
   242     }
       
   243 
       
   244     const GlyphSubstitutionTableHeader *canonGSUBTable =
       
   245         (GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable;
       
   246     LETag scriptTag  = OpenTypeLayoutEngine::getScriptTag(fScriptCode);
   241     LETag scriptTag  = OpenTypeLayoutEngine::getScriptTag(fScriptCode);
   247     LETag langSysTag = OpenTypeLayoutEngine::getLangSysTag(fLanguageCode);
   242     LETag langSysTag = OpenTypeLayoutEngine::getLangSysTag(fLanguageCode);
   248     le_int32 i, dir = 1, out = 0, outCharCount = count;
   243     le_int32 i, dir = 1, out = 0, outCharCount = count;
   249 
   244 
   250     if (canonGSUBTable->coversScript(scriptTag)) {
   245     if (canonGSUBTable->coversScript(scriptTag)) {
   254 
   249 
   255                 // This is the cheapest way to get mark reordering only for Hebrew.
   250                 // This is the cheapest way to get mark reordering only for Hebrew.
   256                 // We could just do the mark reordering for all scripts, but most
   251                 // We could just do the mark reordering for all scripts, but most
   257                 // of them probably don't need it...
   252                 // of them probably don't need it...
   258                 if (fScriptCode == hebrScriptCode) {
   253                 if (fScriptCode == hebrScriptCode) {
   259                     reordered = LE_NEW_ARRAY(LEUnicode, count);
   254                         reordered = LE_NEW_ARRAY(LEUnicode, count);
   260 
   255 
   261                     if (reordered == NULL) {
   256                         if (reordered == NULL) {
   262                         success = LE_MEMORY_ALLOCATION_ERROR;
   257                                 success = LE_MEMORY_ALLOCATION_ERROR;
   263                         return 0;
   258                                 return 0;
   264                     }
   259                         }
   265 
   260 
   266                     CanonShaping::reorderMarks(&chars[offset], count, rightToLeft,
   261                         CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, reordered, glyphStorage);
   267                         reordered, glyphStorage);
   262                         inChars = reordered;
   268                     inChars = reordered;
       
   269                 }
   263                 }
   270 
   264 
   271         glyphStorage.allocateGlyphArray(count, rightToLeft, success);
   265         glyphStorage.allocateGlyphArray(count, rightToLeft, success);
   272         glyphStorage.allocateAuxData(success);
   266         glyphStorage.allocateAuxData(success);
   273 
   267 
   287 
   281 
   288                 if (reordered != NULL) {
   282                 if (reordered != NULL) {
   289                         LE_DELETE_ARRAY(reordered);
   283                         LE_DELETE_ARRAY(reordered);
   290                 }
   284                 }
   291 
   285 
   292         outCharCount = canonGSUBTable->process(glyphStorage, rightToLeft, scriptTag,
   286         outCharCount = canonGSUBTable->process(glyphStorage, rightToLeft, scriptTag, langSysTag, NULL, substitutionFilter, canonFeatureMap, canonFeatureMapCount, FALSE);
   293             langSysTag, NULL, substitutionFilter, canonFeatureMap, canonFeatureMapCount, FALSE);
       
   294 
   287 
   295         out = (rightToLeft? count - 1 : 0);
   288         out = (rightToLeft? count - 1 : 0);
   296 
   289 
   297         outChars = LE_NEW_ARRAY(LEUnicode, outCharCount);
   290         outChars = LE_NEW_ARRAY(LEUnicode, outCharCount);
   298         for (i = 0; i < outCharCount; i += 1, out += dir) {
   291         for (i = 0; i < outCharCount; i += 1, out += dir) {
   303     }
   296     }
   304 
   297 
   305     return outCharCount;
   298     return outCharCount;
   306 }
   299 }
   307 
   300 
   308 
   301 le_int32 LayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
   309 le_int32 LayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 offset,
   302                                             LEGlyphStorage &glyphStorage, LEErrorCode &success)
   310     le_int32 count, le_int32 max, le_bool rightToLeft,
       
   311     LEGlyphStorage &glyphStorage, LEErrorCode &success)
       
   312 {
   303 {
   313     if (LE_FAILURE(success)) {
   304     if (LE_FAILURE(success)) {
   314         return 0;
   305         return 0;
   315     }
   306     }
   316 
   307 
   317     if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max ||
   308     if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) {
   318         offset + count > max) {
       
   319 
       
   320         success = LE_ILLEGAL_ARGUMENT_ERROR;
   309         success = LE_ILLEGAL_ARGUMENT_ERROR;
   321         return 0;
   310         return 0;
   322     }
   311     }
   323 
   312 
   324     LEUnicode *outChars = NULL;
   313     LEUnicode *outChars = NULL;
   325     le_int32 outCharCount = characterProcessing(chars, offset, count, max,
   314     le_int32 outCharCount = characterProcessing(chars, offset, count, max, rightToLeft, outChars, glyphStorage, success);
   326         rightToLeft, outChars, glyphStorage, success);
       
   327 
   315 
   328     if (outChars != NULL) {
   316     if (outChars != NULL) {
   329         mapCharsToGlyphs(outChars, 0, outCharCount, rightToLeft, rightToLeft,
   317         mapCharsToGlyphs(outChars, 0, outCharCount, rightToLeft, rightToLeft, glyphStorage, success);
   330             glyphStorage, success);
   318         LE_DELETE_ARRAY(outChars); // FIXME: a subclass may have allocated this, in which case this delete might not work...
   331         // FIXME: a subclass may have allocated this, in which case this delete
       
   332         // might not work...
       
   333         LE_DELETE_ARRAY(outChars);
       
   334     } else {
   319     } else {
   335         mapCharsToGlyphs(chars, offset, count, rightToLeft, rightToLeft,
   320         mapCharsToGlyphs(chars, offset, count, rightToLeft, rightToLeft, glyphStorage, success);
   336             glyphStorage, success);
       
   337     }
   321     }
   338 
   322 
   339     return glyphStorage.getGlyphCount();
   323     return glyphStorage.getGlyphCount();
   340 }
   324 }
   341 
   325 
   342 // Input: glyphs
   326 // Input: glyphs
   343 // Output: positions
   327 // Output: positions
   344 void LayoutEngine::positionGlyphs(LEGlyphStorage &glyphStorage,
   328 void LayoutEngine::positionGlyphs(LEGlyphStorage &glyphStorage, float x, float y, LEErrorCode &success)
   345     float x, float y, LEErrorCode &success)
       
   346 {
   329 {
   347     if (LE_FAILURE(success)) {
   330     if (LE_FAILURE(success)) {
   348         return;
   331         return;
   349     }
   332     }
   350 
   333 
   367     }
   350     }
   368 
   351 
   369     glyphStorage.setPosition(glyphCount, x, y, success);
   352     glyphStorage.setPosition(glyphCount, x, y, success);
   370 }
   353 }
   371 
   354 
   372 void LayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset,
   355 void LayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse,
   373     le_int32 count, le_bool reverse,
   356                                         LEGlyphStorage &glyphStorage, LEErrorCode &success)
   374     LEGlyphStorage &glyphStorage, LEErrorCode &success)
       
   375 {
   357 {
   376     if (LE_FAILURE(success)) {
   358     if (LE_FAILURE(success)) {
   377         return;
   359         return;
   378     }
   360     }
   379 
   361 
   396 
   378 
   397     // default is no adjustments
   379     // default is no adjustments
   398     return;
   380     return;
   399 }
   381 }
   400 
   382 
   401 void LayoutEngine::adjustMarkGlyphs(LEGlyphStorage &glyphStorage,
   383 void LayoutEngine::adjustMarkGlyphs(LEGlyphStorage &glyphStorage, LEGlyphFilter *markFilter, LEErrorCode &success)
   402     LEGlyphFilter *markFilter, LEErrorCode &success)
       
   403 {
   384 {
   404     float xAdjust = 0;
   385     float xAdjust = 0;
   405     le_int32 p, glyphCount = glyphStorage.getGlyphCount();
   386     le_int32 p, glyphCount = glyphStorage.getGlyphCount();
   406 
   387 
   407     if (LE_FAILURE(success)) {
   388     if (LE_FAILURE(success)) {
   433     }
   414     }
   434 
   415 
   435     glyphStorage.adjustPosition(glyphCount, xAdjust, 0, success);
   416     glyphStorage.adjustPosition(glyphCount, xAdjust, 0, success);
   436 }
   417 }
   437 
   418 
   438 void LayoutEngine::adjustMarkGlyphs(const LEUnicode chars[], le_int32 charCount,
   419 void LayoutEngine::adjustMarkGlyphs(const LEUnicode chars[], le_int32 charCount, le_bool reverse, LEGlyphStorage &glyphStorage, LEGlyphFilter *markFilter, LEErrorCode &success)
   439     le_bool reverse, LEGlyphStorage &glyphStorage, LEGlyphFilter *markFilter,
       
   440     LEErrorCode &success)
       
   441 {
   420 {
   442     float xAdjust = 0;
   421     float xAdjust = 0;
   443     le_int32 c = 0, direction = 1, p;
   422     le_int32 c = 0, direction = 1, p;
   444     le_int32 glyphCount = glyphStorage.getGlyphCount();
   423     le_int32 glyphCount = glyphStorage.getGlyphCount();
   445 
   424 
   482 const void *LayoutEngine::getFontTable(LETag tableTag) const
   461 const void *LayoutEngine::getFontTable(LETag tableTag) const
   483 {
   462 {
   484     return fFontInstance->getFontTable(tableTag);
   463     return fFontInstance->getFontTable(tableTag);
   485 }
   464 }
   486 
   465 
   487 void LayoutEngine::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset,
   466 void LayoutEngine::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool mirror,
   488     le_int32 count, le_bool reverse, le_bool mirror,
   467                                     LEGlyphStorage &glyphStorage, LEErrorCode &success)
   489     LEGlyphStorage &glyphStorage, LEErrorCode &success)
       
   490 {
   468 {
   491     if (LE_FAILURE(success)) {
   469     if (LE_FAILURE(success)) {
   492         return;
   470         return;
   493     }
   471     }
   494 
   472 
   495     glyphStorage.allocateGlyphArray(count, reverse, success);
   473     glyphStorage.allocateGlyphArray(count, reverse, success);
   496 
   474 
   497     DefaultCharMapper charMapper(TRUE, mirror);
   475     DefaultCharMapper charMapper(TRUE, mirror);
   498 
   476 
   499     fFontInstance->mapCharsToGlyphs(chars, offset, count, reverse,
   477     fFontInstance->mapCharsToGlyphs(chars, offset, count, reverse, &charMapper, glyphStorage);
   500         &charMapper, glyphStorage);
       
   501 }
   478 }
   502 
   479 
   503 // Input: characters, font?
   480 // Input: characters, font?
   504 // Output: glyphs, positions, char indices
   481 // Output: glyphs, positions, char indices
   505 // Returns: number of glyphs
   482 // Returns: number of glyphs
   506 le_int32 LayoutEngine::layoutChars(const LEUnicode chars[], le_int32 offset,
   483 le_int32 LayoutEngine::layoutChars(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
   507     le_int32 count, le_int32 max, le_bool rightToLeft,
   484                               float x, float y, LEErrorCode &success)
   508     float x, float y, LEErrorCode &success)
       
   509 {
   485 {
   510     if (LE_FAILURE(success)) {
   486     if (LE_FAILURE(success)) {
   511         return 0;
   487         return 0;
   512     }
   488     }
   513 
   489 
   514     if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max ||
   490     if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) {
   515         offset + count > max) {
       
   516 
       
   517         success = LE_ILLEGAL_ARGUMENT_ERROR;
   491         success = LE_ILLEGAL_ARGUMENT_ERROR;
   518         return 0;
   492         return 0;
   519     }
   493     }
   520 
   494 
   521     le_int32 glyphCount;
   495     le_int32 glyphCount;
   522 
   496 
   523     glyphCount = computeGlyphs(chars, offset, count, max, rightToLeft,
   497     glyphCount = computeGlyphs(chars, offset, count, max, rightToLeft, *fGlyphStorage, success);
   524         *fGlyphStorage, success);
       
   525     positionGlyphs(*fGlyphStorage, x, y, success);
   498     positionGlyphs(*fGlyphStorage, x, y, success);
   526     adjustGlyphPositions(chars, offset, count, rightToLeft, *fGlyphStorage, success);
   499     adjustGlyphPositions(chars, offset, count, rightToLeft, *fGlyphStorage, success);
   527 
   500 
   528     return glyphCount;
   501     return glyphCount;
   529 }
   502 }
   531 void LayoutEngine::reset()
   504 void LayoutEngine::reset()
   532 {
   505 {
   533     fGlyphStorage->reset();
   506     fGlyphStorage->reset();
   534 }
   507 }
   535 
   508 
   536 LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstance,
   509 LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, LEErrorCode &success)
   537     le_int32 scriptCode, le_int32 languageCode, LEErrorCode &success)
       
   538 {
   510 {
   539   // 3 -> kerning and ligatures
   511   // 3 -> kerning and ligatures
   540   return LayoutEngine::layoutEngineFactory(fontInstance, scriptCode,
   512   return LayoutEngine::layoutEngineFactory(fontInstance, scriptCode, languageCode, 3, success);
   541         languageCode, 3, success);
   513 }
   542 }
   514 
   543 
   515 LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success)
   544 LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstance,
       
   545     le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags,
       
   546     LEErrorCode &success)
       
   547 {
   516 {
   548     static const le_uint32 gsubTableTag = LE_GSUB_TABLE_TAG;
   517     static const le_uint32 gsubTableTag = LE_GSUB_TABLE_TAG;
   549     static const le_uint32 mortTableTag = LE_MORT_TABLE_TAG;
   518     static const le_uint32 mortTableTag = LE_MORT_TABLE_TAG;
   550 
   519 
   551     if (LE_FAILURE(success)) {
   520     if (LE_FAILURE(success)) {
   552         return NULL;
   521         return NULL;
   553     }
   522     }
   554 
   523 
   555     // code2000 has GPOS kern feature tags for latn script
   524     const GlyphSubstitutionTableHeader *gsubTable = (const GlyphSubstitutionTableHeader *) fontInstance->getFontTable(gsubTableTag);
   556 
       
   557     const GlyphSubstitutionTableHeader *gsubTable =
       
   558         (const GlyphSubstitutionTableHeader *) fontInstance->getFontTable(gsubTableTag);
       
   559     LayoutEngine *result = NULL;
   525     LayoutEngine *result = NULL;
   560     LETag scriptTag   = 0x00000000;
   526     LETag scriptTag   = 0x00000000;
   561     LETag languageTag = 0x00000000;
   527     LETag languageTag = 0x00000000;
   562 
   528 
   563     if (gsubTable != NULL &&
   529     if (gsubTable != NULL && gsubTable->coversScript(scriptTag = OpenTypeLayoutEngine::getScriptTag(scriptCode))) {
   564         gsubTable->coversScript(scriptTag =
       
   565             OpenTypeLayoutEngine::getScriptTag(scriptCode))) {
       
   566 
       
   567         switch (scriptCode) {
   530         switch (scriptCode) {
   568         case bengScriptCode:
   531         case bengScriptCode:
   569         case devaScriptCode:
   532         case devaScriptCode:
   570         case gujrScriptCode:
   533         case gujrScriptCode:
   571         case kndaScriptCode:
   534         case kndaScriptCode:
   573         case oryaScriptCode:
   536         case oryaScriptCode:
   574         case guruScriptCode:
   537         case guruScriptCode:
   575         case tamlScriptCode:
   538         case tamlScriptCode:
   576         case teluScriptCode:
   539         case teluScriptCode:
   577         case sinhScriptCode:
   540         case sinhScriptCode:
   578             result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode,
   541             result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable);
   579              languageCode, typoFlags, gsubTable);
       
   580             break;
   542             break;
   581 
   543 
   582         case arabScriptCode:
   544         case arabScriptCode:
   583             result = new ArabicOpenTypeLayoutEngine(fontInstance, scriptCode,
   545             result = new ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable);
   584              languageCode, typoFlags, gsubTable);
       
   585             break;
   546             break;
   586 
   547 
   587         case haniScriptCode:
   548         case haniScriptCode:
   588             languageTag = OpenTypeLayoutEngine::getLangSysTag(languageCode);
   549             languageTag = OpenTypeLayoutEngine::getLangSysTag(languageCode);
   589 
   550 
   591             case korLanguageCode:
   552             case korLanguageCode:
   592             case janLanguageCode:
   553             case janLanguageCode:
   593             case zhtLanguageCode:
   554             case zhtLanguageCode:
   594             case zhsLanguageCode:
   555             case zhsLanguageCode:
   595                 if (gsubTable->coversScriptAndLanguage(scriptTag, languageTag, TRUE)) {
   556                 if (gsubTable->coversScriptAndLanguage(scriptTag, languageTag, TRUE)) {
   596                     result = new HanOpenTypeLayoutEngine(fontInstance, scriptCode,
   557                     result = new HanOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable);
   597                         languageCode, typoFlags, gsubTable);
       
   598                     break;
   558                     break;
   599                 }
   559                 }
   600 
   560 
   601                 // note: falling through to default case.
   561                 // note: falling through to default case.
   602             default:
   562             default:
   603                 result = new OpenTypeLayoutEngine(fontInstance, scriptCode,
   563                 result = new OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable);
   604                  languageCode, typoFlags, gsubTable);
       
   605                 break;
   564                 break;
   606             }
   565             }
   607 
   566 
   608             break;
   567             break;
       
   568 #if 0
       
   569         case tibtScriptCode:
       
   570              result = new TibetanOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable);
       
   571             break;
       
   572 #endif
   609 
   573 
   610         case khmrScriptCode:
   574         case khmrScriptCode:
   611             result = new KhmerOpenTypeLayoutEngine(fontInstance, scriptCode,
   575             result = new KhmerOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable);
   612                 languageCode, typoFlags, gsubTable);
       
   613             break;
   576             break;
   614 
   577 
   615         default:
   578         default:
   616             result = new OpenTypeLayoutEngine(fontInstance, scriptCode,
   579             result = new OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable);
   617              languageCode, typoFlags, gsubTable);
       
   618             break;
   580             break;
   619         }
   581         }
   620     } else {
   582     } else {
   621         const MorphTableHeader *morphTable =
   583         const MorphTableHeader *morphTable = (MorphTableHeader *) fontInstance->getFontTable(mortTableTag);
   622           (MorphTableHeader *) fontInstance->getFontTable(mortTableTag);
       
   623 
   584 
   624         if (morphTable != NULL) {
   585         if (morphTable != NULL) {
   625             result = new GXLayoutEngine(fontInstance, scriptCode, languageCode, morphTable);
   586             result = new GXLayoutEngine(fontInstance, scriptCode, languageCode, morphTable);
   626         } else {
   587         } else {
   627             switch (scriptCode) {
   588             switch (scriptCode) {
   634             case guruScriptCode:
   595             case guruScriptCode:
   635             case tamlScriptCode:
   596             case tamlScriptCode:
   636             case teluScriptCode:
   597             case teluScriptCode:
   637             case sinhScriptCode:
   598             case sinhScriptCode:
   638             {
   599             {
   639                 result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode,
   600                 result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags);
   640                 languageCode, typoFlags);
       
   641                 break;
   601                 break;
   642             }
   602             }
   643 
   603 
   644             case arabScriptCode:
   604             case arabScriptCode:
   645                 result = new UnicodeArabicOpenTypeLayoutEngine(fontInstance, scriptCode,
   605             //case hebrScriptCode:
   646                     languageCode, typoFlags);
   606                 result = new UnicodeArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags);
   647                 break;
   607                 break;
       
   608 
       
   609             //case hebrScriptCode:
       
   610             //    return new HebrewOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags);
   648 
   611 
   649             case thaiScriptCode:
   612             case thaiScriptCode:
   650                 result = new ThaiLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags);
   613                 result = new ThaiLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags);
   651                 break;
   614                 break;
   652 
   615 
   665 }
   628 }
   666 
   629 
   667 LayoutEngine::~LayoutEngine() {
   630 LayoutEngine::~LayoutEngine() {
   668     delete fGlyphStorage;
   631     delete fGlyphStorage;
   669 }
   632 }
       
   633 
       
   634 U_NAMESPACE_END