jdk/src/share/native/sun/font/layout/ScriptAndLanguage.cpp
changeset 16891 91e99bed64ae
parent 7486 6a36b1ebc620
child 22330 cafb826672bd
equal deleted inserted replaced
16890:36b30720a997 16891:91e99bed64ae
    36 #include "ScriptAndLanguage.h"
    36 #include "ScriptAndLanguage.h"
    37 #include "LESwaps.h"
    37 #include "LESwaps.h"
    38 
    38 
    39 U_NAMESPACE_BEGIN
    39 U_NAMESPACE_BEGIN
    40 
    40 
    41 const LangSysTable *ScriptTable::findLanguage(LETag languageTag, le_bool exactMatch) const
    41 LEReferenceTo<LangSysTable> ScriptTable::findLanguage(const LETableReference& base, LETag languageTag, LEErrorCode &success, le_bool exactMatch) const
    42 {
    42 {
    43     le_uint16 count = SWAPW(langSysCount);
    43     le_uint16 count = SWAPW(langSysCount);
    44     Offset langSysTableOffset = exactMatch? 0 : SWAPW(defaultLangSysTableOffset);
    44     Offset langSysTableOffset = exactMatch? 0 : SWAPW(defaultLangSysTableOffset);
    45 
    45 
    46     if (count > 0) {
    46     if (count > 0) {
    47         Offset foundOffset =
    47       LEReferenceToArrayOf<TagAndOffsetRecord> langSysRecords(base, success, langSysRecordArray, count);
    48             OpenTypeUtilities::getTagOffset(languageTag, langSysRecordArray, count);
    48       Offset foundOffset =
       
    49         OpenTypeUtilities::getTagOffset(languageTag, langSysRecords, success);
    49 
    50 
    50         if (foundOffset != 0) {
    51       if (foundOffset != 0 && LE_SUCCESS(success)) {
    51             langSysTableOffset = foundOffset;
    52         langSysTableOffset = foundOffset;
    52         }
    53       }
    53     }
    54     }
    54 
    55 
    55     if (langSysTableOffset != 0) {
    56     if (langSysTableOffset != 0) {
    56         return (const LangSysTable *) ((char *)this + langSysTableOffset);
    57       return LEReferenceTo<LangSysTable>(base, success, langSysTableOffset);
    57     }
    58     }
    58 
    59 
    59     return NULL;
    60     return LEReferenceTo<LangSysTable>();
    60 }
    61 }
    61 
    62 
    62 const ScriptTable *ScriptListTable::findScript(LETag scriptTag) const
    63 LEReferenceTo<ScriptTable> ScriptListTable::findScript(const LETableReference &base, LETag scriptTag, LEErrorCode &success) const
    63 {
    64 {
       
    65     if (LE_FAILURE(success) ) {
       
    66       return LEReferenceTo<ScriptTable>(); // get out
       
    67     }
    64     /*
    68     /*
    65      * There are some fonts that have a large, bogus value for scriptCount. To try
    69      * There are some fonts that have a large, bogus value for scriptCount. To try
    66      * and protect against this, we use the offset in the first scriptRecord,
    70      * and protect against this, we use the offset in the first scriptRecord,
    67      * which we know has to be past the end of the scriptRecordArray, to compute
    71      * which we know has to be past the end of the scriptRecordArray, to compute
    68      * a value which is greater than or equal to the actual script count.
    72      * a value which is greater than or equal to the actual script count.
    72      * Because of this, a binary serach isn't safe, because the new count may include
    76      * Because of this, a binary serach isn't safe, because the new count may include
    73      * data that's not actually in the scriptRecordArray and hence the array will appear
    77      * data that's not actually in the scriptRecordArray and hence the array will appear
    74      * to be unsorted.
    78      * to be unsorted.
    75      */
    79      */
    76     le_uint16 count = SWAPW(scriptCount);
    80     le_uint16 count = SWAPW(scriptCount);
       
    81 
       
    82     if (count == 0) {
       
    83       return LEReferenceTo<ScriptTable>(); // no items, no search
       
    84     }
       
    85 
       
    86     // attempt to construct a ref with at least one element
       
    87     LEReferenceToArrayOf<ScriptRecord> oneElementTable(base, success, &scriptRecordArray[0], 1);
       
    88 
       
    89     if( LE_FAILURE(success) ) {
       
    90       return LEReferenceTo<ScriptTable>(); // couldn't even read the first record - bad font.
       
    91     }
       
    92 
    77     le_uint16 limit = ((SWAPW(scriptRecordArray[0].offset) - sizeof(ScriptListTable)) / sizeof(scriptRecordArray)) + ANY_NUMBER;
    93     le_uint16 limit = ((SWAPW(scriptRecordArray[0].offset) - sizeof(ScriptListTable)) / sizeof(scriptRecordArray)) + ANY_NUMBER;
    78     Offset scriptTableOffset = 0;
    94     Offset scriptTableOffset = 0;
       
    95 
    79 
    96 
    80     if (count > limit) {
    97     if (count > limit) {
    81         // the scriptCount value is bogus; do a linear search
    98         // the scriptCount value is bogus; do a linear search
    82         // because limit may still be too large.
    99         // because limit may still be too large.
    83         for(le_int32 s = 0; s < limit; s += 1) {
   100         LEReferenceToArrayOf<ScriptRecord> scriptRecordArrayRef(base, success, &scriptRecordArray[0], limit);
    84             if (SWAPT(scriptRecordArray[s].tag) == scriptTag) {
   101         for(le_int32 s = 0; (s < limit)&&LE_SUCCESS(success); s += 1) {
    85                 scriptTableOffset = SWAPW(scriptRecordArray[s].offset);
   102           if (SWAPT(scriptRecordArrayRef(s,success).tag) == scriptTag) {
    86                 break;
   103             scriptTableOffset = SWAPW(scriptRecordArrayRef(s,success).offset);
    87             }
   104             break;
       
   105           }
    88         }
   106         }
    89     } else {
   107     } else {
    90         scriptTableOffset = OpenTypeUtilities::getTagOffset(scriptTag, scriptRecordArray, count);
   108       LEReferenceToArrayOf<ScriptRecord> scriptRecordArrayRef(base, success, &scriptRecordArray[0], count);
       
   109       scriptTableOffset = OpenTypeUtilities::getTagOffset(scriptTag, scriptRecordArrayRef, success); // TODO
    91     }
   110     }
    92 
   111 
    93     if (scriptTableOffset != 0) {
   112     if (scriptTableOffset != 0) {
    94         return (const ScriptTable *) ((char *)this + scriptTableOffset);
   113       return LEReferenceTo<ScriptTable>(base, success, scriptTableOffset);
    95     }
   114     }
    96 
   115 
    97     return NULL;
   116   return LEReferenceTo<ScriptTable>();
    98 }
   117 }
    99 
   118 
   100 const LangSysTable *ScriptListTable::findLanguage(LETag scriptTag, LETag languageTag, le_bool exactMatch) const
   119 LEReferenceTo<LangSysTable>  ScriptListTable::findLanguage(const LETableReference &base, LETag scriptTag, LETag languageTag, LEErrorCode &success, le_bool exactMatch) const
   101 {
   120 {
   102     const ScriptTable *scriptTable = findScript(scriptTag);
   121   const LEReferenceTo<ScriptTable> scriptTable = findScript(base, scriptTag, success);
   103 
   122 
   104     if (scriptTable == 0) {
   123   if (scriptTable.isEmpty()) {
   105         return NULL;
   124     return LEReferenceTo<LangSysTable>();
   106     }
   125   }
   107 
   126 
   108     return scriptTable->findLanguage(languageTag, exactMatch);
   127   return scriptTable->findLanguage(scriptTable, languageTag, success, exactMatch).reparent(base);
   109 }
   128 }
   110 
   129 
   111 U_NAMESPACE_END
   130 U_NAMESPACE_END