2 * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
7 #include "OpenTypeTables.h"
8 #include "OpenTypeUtilities.h"
9 #include "ScriptAndLanguage.h"
14 LEReferenceTo
<LangSysTable
> ScriptTable::findLanguage(const LETableReference
& base
, LETag languageTag
, LEErrorCode
&success
, le_bool exactMatch
) const
16 le_uint16 count
= SWAPW(langSysCount
);
17 Offset langSysTableOffset
= exactMatch
? 0 : SWAPW(defaultLangSysTableOffset
);
20 LEReferenceToArrayOf
<TagAndOffsetRecord
> langSysRecords(base
, success
, langSysRecordArray
, count
);
22 OpenTypeUtilities::getTagOffset(languageTag
, langSysRecords
, success
);
24 if (foundOffset
!= 0 && LE_SUCCESS(success
)) {
25 langSysTableOffset
= foundOffset
;
29 if (langSysTableOffset
!= 0) {
30 return LEReferenceTo
<LangSysTable
>(base
, success
, langSysTableOffset
);
33 return LEReferenceTo
<LangSysTable
>();
36 LEReferenceTo
<ScriptTable
> ScriptListTable::findScript(const LETableReference
&base
, LETag scriptTag
, LEErrorCode
&success
) const
38 if (LE_FAILURE(success
) ) {
39 return LEReferenceTo
<ScriptTable
>(); // get out
42 * There are some fonts that have a large, bogus value for scriptCount. To try
43 * and protect against this, we use the offset in the first scriptRecord,
44 * which we know has to be past the end of the scriptRecordArray, to compute
45 * a value which is greater than or equal to the actual script count.
47 * Note: normally, the first offset will point to just after the scriptRecordArray,
48 * but there's no guarantee of this, only that it's *after* the scriptRecordArray.
49 * Because of this, a binary serach isn't safe, because the new count may include
50 * data that's not actually in the scriptRecordArray and hence the array will appear
53 le_uint16 count
= SWAPW(scriptCount
);
56 return LEReferenceTo
<ScriptTable
>(); // no items, no search
59 // attempt to construct a ref with at least one element
60 LEReferenceToArrayOf
<ScriptRecord
> oneElementTable(base
, success
, &scriptRecordArray
[0], 1);
62 if( LE_FAILURE(success
) ) {
63 return LEReferenceTo
<ScriptTable
>(); // couldn't even read the first record - bad font.
66 le_uint16 limit
= ((SWAPW(scriptRecordArray
[0].offset
) - sizeof(ScriptListTable
)) / sizeof(scriptRecordArray
)) + ANY_NUMBER
;
67 Offset scriptTableOffset
= 0;
71 // the scriptCount value is bogus; do a linear search
72 // because limit may still be too large.
73 LEReferenceToArrayOf
<ScriptRecord
> scriptRecordArrayRef(base
, success
, &scriptRecordArray
[0], limit
);
74 for(le_int32 s
= 0; (s
< limit
)&&LE_SUCCESS(success
); s
+= 1) {
75 if (SWAPT(scriptRecordArrayRef(s
,success
).tag
) == scriptTag
) {
76 scriptTableOffset
= SWAPW(scriptRecordArrayRef(s
,success
).offset
);
81 LEReferenceToArrayOf
<ScriptRecord
> scriptRecordArrayRef(base
, success
, &scriptRecordArray
[0], count
);
83 scriptTableOffset
= OpenTypeUtilities::getTagOffset(scriptTag
, scriptRecordArrayRef
, success
);
86 if (scriptTableOffset
!= 0) {
87 return LEReferenceTo
<ScriptTable
>(base
, success
, scriptTableOffset
);
90 return LEReferenceTo
<ScriptTable
>();
93 LEReferenceTo
<LangSysTable
> ScriptListTable::findLanguage(const LETableReference
&base
, LETag scriptTag
, LETag languageTag
, LEErrorCode
&success
, le_bool exactMatch
) const
95 const LEReferenceTo
<ScriptTable
> scriptTable
= findScript(base
, scriptTag
, success
);
97 if (scriptTable
.isEmpty()) {
98 return LEReferenceTo
<LangSysTable
>();
101 return scriptTable
->findLanguage(scriptTable
, languageTag
, success
, exactMatch
).reparent(base
);