]> git.saurik.com Git - apple/icu.git/blame - icuSources/layout/ScriptAndLanguage.cpp
ICU-491.11.1.tar.gz
[apple/icu.git] / icuSources / layout / ScriptAndLanguage.cpp
CommitLineData
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
12U_NAMESPACE_BEGIN
13
14const 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
35const 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
73const 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
84U_NAMESPACE_END