1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved 3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "LETypes.h" 7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "OpenTypeTables.h" 8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "OpenTypeUtilities.h" 9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ScriptAndLanguage.h" 10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "LESwaps.h" 11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_BEGIN 13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst LangSysTable *ScriptTable::findLanguage(LETag languageTag, le_bool exactMatch) const 15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_uint16 count = SWAPW(langSysCount); 17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Offset langSysTableOffset = exactMatch? 0 : SWAPW(defaultLangSysTableOffset); 18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (count > 0) { 20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Offset foundOffset = 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru OpenTypeUtilities::getTagOffset(languageTag, langSysRecordArray, count); 22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (foundOffset != 0) { 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru langSysTableOffset = foundOffset; 25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (langSysTableOffset != 0) { 29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (const LangSysTable *) ((char *)this + langSysTableOffset); 30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 3285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return NULL; 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst ScriptTable *ScriptListTable::findScript(LETag scriptTag) const 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 3785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* 3885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * There are some fonts that have a large, bogus value for scriptCount. To try 3985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * and protect against this, we use the offset in the first scriptRecord, 4085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * which we know has to be past the end of the scriptRecordArray, to compute 4185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * a value which is greater than or equal to the actual script count. 4285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * 4385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * Note: normally, the first offset will point to just after the scriptRecordArray, 4485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * but there's no guarantee of this, only that it's *after* the scriptRecordArray. 4585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * Because of this, a binary serach isn't safe, because the new count may include 4685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * data that's not actually in the scriptRecordArray and hence the array will appear 4785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * to be unsorted. 4885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho */ 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_uint16 count = SWAPW(scriptCount); 5085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho le_uint16 limit = ((SWAPW(scriptRecordArray[0].offset) - sizeof(ScriptListTable)) / sizeof(scriptRecordArray)) + ANY_NUMBER; 5185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho Offset scriptTableOffset = 0; 5285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 5385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (count > limit) { 5485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho // the scriptCount value is bogus; do a linear search 5585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho // because limit may still be too large. 5685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho for(le_int32 s = 0; s < limit; s += 1) { 5785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (SWAPT(scriptRecordArray[s].tag) == scriptTag) { 5885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho scriptTableOffset = SWAPW(scriptRecordArray[s].offset); 5985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho break; 6085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 6185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 6285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } else { 6385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho scriptTableOffset = OpenTypeUtilities::getTagOffset(scriptTag, scriptRecordArray, count); 6485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (scriptTableOffset != 0) { 67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (const ScriptTable *) ((char *)this + scriptTableOffset); 68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 7085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return NULL; 71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst LangSysTable *ScriptListTable::findLanguage(LETag scriptTag, LETag languageTag, le_bool exactMatch) const 74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const ScriptTable *scriptTable = findScript(scriptTag); 76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (scriptTable == 0) { 7885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return NULL; 79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return scriptTable->findLanguage(languageTag, exactMatch); 82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_END 85