]>
Commit | Line | Data |
---|---|---|
b75a7d8f | 1 | /* |
46f4442e | 2 | * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved |
b75a7d8f A |
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 | ||
46f4442e | 32 | return NULL; |
b75a7d8f A |
33 | } |
34 | ||
35 | const ScriptTable *ScriptListTable::findScript(LETag scriptTag) const | |
36 | { | |
46f4442e A |
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 | */ | |
b75a7d8f | 49 | le_uint16 count = SWAPW(scriptCount); |
46f4442e A |
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 | } | |
b75a7d8f A |
65 | |
66 | if (scriptTableOffset != 0) { | |
67 | return (const ScriptTable *) ((char *)this + scriptTableOffset); | |
68 | } | |
69 | ||
46f4442e | 70 | return NULL; |
b75a7d8f A |
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) { | |
46f4442e | 78 | return NULL; |
b75a7d8f A |
79 | } |
80 | ||
81 | return scriptTable->findLanguage(languageTag, exactMatch); | |
82 | } | |
83 | ||
84 | U_NAMESPACE_END |