]> git.saurik.com Git - apple/icu.git/blob - icuSources/layout/ScriptAndLanguage.cpp
ICU-491.11.1.tar.gz
[apple/icu.git] / icuSources / layout / ScriptAndLanguage.cpp
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