1 /* 2 * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved 3 * 4 */ 5 6 #include "LETypes.h" 7 #include "OpenTypeTables.h" 8 #include "OpenTypeUtilities.h" 9 #include "ScriptAndLanguage.h" 10 #include "LESwaps.h" 11 12 U_NAMESPACE_BEGIN 13 14 const LangSysTable *ScriptTable::findLanguage(LETag languageTag, le_bool exactMatch) const 15 { 16 le_uint16 count = SWAPW(langSysCount); 17 Offset langSysTableOffset = exactMatch? 0 : SWAPW(defaultLangSysTableOffset); 18 19 if (count > 0) { 20 Offset foundOffset = 21 OpenTypeUtilities::getTagOffset(languageTag, langSysRecordArray, count); 22 23 if (foundOffset != 0) { 24 langSysTableOffset = foundOffset; 25 } 26 } 27 28 if (langSysTableOffset != 0) { 29 return (const LangSysTable *) ((char *)this + langSysTableOffset); 30 } 31 32 return NULL; 33 } 34 35 const ScriptTable *ScriptListTable::findScript(LETag scriptTag) const 36 { 37 /* 38 * There are some fonts that have a large, bogus value for scriptCount. To try 39 * and protect against this, we use the offset in the first scriptRecord, 40 * which we know has to be past the end of the scriptRecordArray, to compute 41 * a value which is greater than or equal to the actual script count. 42 * 43 * Note: normally, the first offset will point to just after the scriptRecordArray, 44 * but there's no guarantee of this, only that it's *after* the scriptRecordArray. 45 * Because of this, a binary serach isn't safe, because the new count may include 46 * data that's not actually in the scriptRecordArray and hence the array will appear 47 * to be unsorted. 48 */ 49 le_uint16 count = SWAPW(scriptCount); 50 le_uint16 limit = ((SWAPW(scriptRecordArray[0].offset) - sizeof(ScriptListTable)) / sizeof(scriptRecordArray)) + ANY_NUMBER; 51 Offset scriptTableOffset = 0; 52 53 if (count > limit) { 54 // the scriptCount value is bogus; do a linear search 55 // because limit may still be too large. 56 for(le_int32 s = 0; s < limit; s += 1) { 57 if (SWAPT(scriptRecordArray[s].tag) == scriptTag) { 58 scriptTableOffset = SWAPW(scriptRecordArray[s].offset); 59 break; 60 } 61 } 62 } else { 63 scriptTableOffset = OpenTypeUtilities::getTagOffset(scriptTag, scriptRecordArray, count); 64 } 65 66 if (scriptTableOffset != 0) { 67 return (const ScriptTable *) ((char *)this + scriptTableOffset); 68 } 69 70 return NULL; 71 } 72 73 const LangSysTable *ScriptListTable::findLanguage(LETag scriptTag, LETag languageTag, le_bool exactMatch) const 74 { 75 const ScriptTable *scriptTable = findScript(scriptTag); 76 77 if (scriptTable == 0) { 78 return NULL; 79 } 80 81 return scriptTable->findLanguage(languageTag, exactMatch); 82 } 83 84 U_NAMESPACE_END 85