11512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* 21512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * Copyright (C) 1998-2004 David Turner and Werner Lemberg 31512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * Copyright (C) 2006 Behdad Esfahbod 41512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * 51512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * This is part of HarfBuzz, an OpenType Layout engine library. 61512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * 71512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * Permission is hereby granted, without written agreement and without 81512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this 91512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * software and its documentation for any purpose, provided that the 101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * above copyright notice and the following two paragraphs appear in 111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * all copies of this software. 121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * 131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * DAMAGE. 181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * 191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod */ 251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#include "harfbuzz-impl.h" 271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#include "harfbuzz-open-private.h" 281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/*************************** 311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * Script related functions 321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod ***************************/ 331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* LangSys */ 361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_Error Load_LangSys( HB_LangSys* ls, 381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Stream stream ) 391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Error error; 411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort n, count; 421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort* fi; 431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ACCESS_Frame( 6L ) ) 461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod ls->LookupOrderOffset = GET_UShort(); /* should be 0 */ 491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod ls->ReqFeatureIndex = GET_UShort(); 501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod count = ls->FeatureCount = GET_UShort(); 511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FORGET_Frame(); 531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod ls->FeatureIndex = NULL; 551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ALLOC_ARRAY( ls->FeatureIndex, count, HB_UShort ) ) 571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ACCESS_Frame( count * 2L ) ) 601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( ls->FeatureIndex ); 621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod fi = ls->FeatureIndex; 661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod for ( n = 0; n < count; n++ ) 681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod fi[n] = GET_UShort(); 691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FORGET_Frame(); 711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Ok; 731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic void Free_LangSys( HB_LangSys* ls ) 771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( ls->FeatureIndex ); 791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* Script */ 831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_Error Load_Script( HB_ScriptTable* s, 851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Stream stream ) 861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Error error; 881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort n, m, count; 891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UInt cur_offset, new_offset, base_offset; 901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_LangSysRecord* lsr; 921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod base_offset = FILE_Pos(); 951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ACCESS_Frame( 2L ) ) 971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod new_offset = GET_UShort() + base_offset; 1001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FORGET_Frame(); 1021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( new_offset != base_offset ) /* not a NULL offset */ 1041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 1051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod cur_offset = FILE_Pos(); 1061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( FILE_Seek( new_offset ) || 1071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod ( error = Load_LangSys( &s->DefaultLangSys, 1081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod stream ) ) != HB_Err_Ok ) 1091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 1101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod (void)FILE_Seek( cur_offset ); 1111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 1121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod else 1131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 1141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod /* we create a DefaultLangSys table with no entries */ 1151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod s->DefaultLangSys.LookupOrderOffset = 0; 1171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod s->DefaultLangSys.ReqFeatureIndex = 0xFFFF; 1181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod s->DefaultLangSys.FeatureCount = 0; 1191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod s->DefaultLangSys.FeatureIndex = NULL; 1201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 1211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ACCESS_Frame( 2L ) ) 1231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod goto Fail2; 1241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod count = s->LangSysCount = GET_UShort(); 1261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod /* safety check; otherwise the official handling of TrueType Open 1281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod fonts won't work */ 1291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( s->LangSysCount == 0 && s->DefaultLangSys.FeatureCount == 0 ) 1311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 1321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod error = HB_Err_Not_Covered; 1331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod goto Fail2; 1341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 1351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FORGET_Frame(); 1371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod s->LangSysRecord = NULL; 1391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ALLOC_ARRAY( s->LangSysRecord, count, HB_LangSysRecord ) ) 1411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod goto Fail2; 1421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod lsr = s->LangSysRecord; 1441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod for ( n = 0; n < count; n++ ) 1461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 1471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ACCESS_Frame( 6L ) ) 1481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod goto Fail1; 1491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod lsr[n].LangSysTag = GET_ULong(); 1511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod new_offset = GET_UShort() + base_offset; 1521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FORGET_Frame(); 1541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod cur_offset = FILE_Pos(); 1561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( FILE_Seek( new_offset ) || 1571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod ( error = Load_LangSys( &lsr[n].LangSys, stream ) ) != HB_Err_Ok ) 1581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod goto Fail1; 1591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod (void)FILE_Seek( cur_offset ); 1601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 1611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Ok; 1631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1641512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodFail1: 1651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod for ( m = 0; m < n; m++ ) 1661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod Free_LangSys( &lsr[m].LangSys ); 1671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( s->LangSysRecord ); 1691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1701512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodFail2: 1711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod Free_LangSys( &s->DefaultLangSys ); 1721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 1731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 1741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic void Free_Script( HB_ScriptTable* s ) 1771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 1781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort n, count; 1791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_LangSysRecord* lsr; 1811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod Free_LangSys( &s->DefaultLangSys ); 1841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( s->LangSysRecord ) 1861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 1871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod count = s->LangSysCount; 1881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod lsr = s->LangSysRecord; 1891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod for ( n = 0; n < count; n++ ) 1911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod Free_LangSys( &lsr[n].LangSys ); 1921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( lsr ); 1941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 1951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 1961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* ScriptList */ 1991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2001512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_INTERNAL HB_Error 2011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod_HB_OPEN_Load_ScriptList( HB_ScriptList* sl, 2021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Stream stream ) 2031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 2041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Error error; 2051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort n, script_count; 2071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UInt cur_offset, new_offset, base_offset; 2081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_ScriptRecord* sr; 2101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod base_offset = FILE_Pos(); 2131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ACCESS_Frame( 2L ) ) 2151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 2161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod script_count = GET_UShort(); 2181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FORGET_Frame(); 2201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod sl->ScriptRecord = NULL; 2221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ALLOC_ARRAY( sl->ScriptRecord, script_count, HB_ScriptRecord ) ) 2241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 2251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod sr = sl->ScriptRecord; 2271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod sl->ScriptCount= 0; 2291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod for ( n = 0; n < script_count; n++ ) 2301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 2311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ACCESS_Frame( 6L ) ) 2321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod goto Fail; 2331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod sr[sl->ScriptCount].ScriptTag = GET_ULong(); 2351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod new_offset = GET_UShort() + base_offset; 2361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FORGET_Frame(); 2381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod cur_offset = FILE_Pos(); 2401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( FILE_Seek( new_offset ) ) 2421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod goto Fail; 2431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod error = Load_Script( &sr[sl->ScriptCount].Script, stream ); 2451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( error == HB_Err_Ok ) 2461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod sl->ScriptCount += 1; 2471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod else if ( error != HB_Err_Not_Covered ) 2481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod goto Fail; 2491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod (void)FILE_Seek( cur_offset ); 2511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 2521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod /* Empty tables are harmless and generated by fontforge. 2541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * See http://bugzilla.gnome.org/show_bug.cgi?id=347073 2551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod */ 2561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#if 0 2571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( sl->ScriptCount == 0 ) 2581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 2591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod error = ERR(HB_Err_Invalid_SubTable); 2601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod goto Fail; 2611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 2621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#endif 2631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Ok; 2651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2661512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodFail: 2671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod for ( n = 0; n < sl->ScriptCount; n++ ) 2681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod Free_Script( &sr[n].Script ); 2691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( sl->ScriptRecord ); 2711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 2721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 2731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2751512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_INTERNAL void 2761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod_HB_OPEN_Free_ScriptList( HB_ScriptList* sl ) 2771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 2781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort n, count; 2791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_ScriptRecord* sr; 2811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( sl->ScriptRecord ) 2841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 2851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod count = sl->ScriptCount; 2861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod sr = sl->ScriptRecord; 2871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod for ( n = 0; n < count; n++ ) 2891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod Free_Script( &sr[n].Script ); 2901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( sr ); 2921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 2931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 2941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/********************************* 2981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * Feature List related functions 2991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod *********************************/ 3001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* Feature */ 3031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_Error Load_Feature( HB_Feature* f, 3051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Stream stream ) 3061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 3071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Error error; 3081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort n, count; 3101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort* lli; 3121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ACCESS_Frame( 4L ) ) 3151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 3161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod f->FeatureParams = GET_UShort(); /* should be 0 */ 3181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod count = f->LookupListCount = GET_UShort(); 3191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FORGET_Frame(); 3211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod f->LookupListIndex = NULL; 3231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ALLOC_ARRAY( f->LookupListIndex, count, HB_UShort ) ) 3251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 3261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod lli = f->LookupListIndex; 3281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ACCESS_Frame( count * 2L ) ) 3301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 3311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( f->LookupListIndex ); 3321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 3331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 3341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod for ( n = 0; n < count; n++ ) 3361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod lli[n] = GET_UShort(); 3371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FORGET_Frame(); 3391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Ok; 3411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 3421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic void Free_Feature( HB_Feature* f ) 3451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 3461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( f->LookupListIndex ); 3471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 3481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* FeatureList */ 3511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3521512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_INTERNAL HB_Error 3531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod_HB_OPEN_Load_FeatureList( HB_FeatureList* fl, 3541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Stream stream ) 3551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 3561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Error error; 3571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort n, m, count; 3591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UInt cur_offset, new_offset, base_offset; 3601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_FeatureRecord* fr; 3621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod base_offset = FILE_Pos(); 3651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ACCESS_Frame( 2L ) ) 3671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 3681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod count = fl->FeatureCount = GET_UShort(); 3701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FORGET_Frame(); 3721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod fl->FeatureRecord = NULL; 3741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ALLOC_ARRAY( fl->FeatureRecord, count, HB_FeatureRecord ) ) 3761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 3771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ALLOC_ARRAY( fl->ApplyOrder, count, HB_UShort ) ) 3781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod goto Fail2; 3791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod fl->ApplyCount = 0; 3811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod fr = fl->FeatureRecord; 3831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod for ( n = 0; n < count; n++ ) 3851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 3861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ACCESS_Frame( 6L ) ) 3871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod goto Fail1; 3881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod fr[n].FeatureTag = GET_ULong(); 3901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod new_offset = GET_UShort() + base_offset; 3911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FORGET_Frame(); 3931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 3941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod cur_offset = FILE_Pos(); 3951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( FILE_Seek( new_offset ) || 3961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod ( error = Load_Feature( &fr[n].Feature, stream ) ) != HB_Err_Ok ) 3971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod goto Fail1; 3981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod (void)FILE_Seek( cur_offset ); 3991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 4001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Ok; 4021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4031512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodFail1: 4041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod for ( m = 0; m < n; m++ ) 4051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod Free_Feature( &fr[m].Feature ); 4061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( fl->ApplyOrder ); 4081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4091512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodFail2: 4101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( fl->FeatureRecord ); 4111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 4131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 4141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4161512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_INTERNAL void 4171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod_HB_OPEN_Free_FeatureList( HB_FeatureList* fl ) 4181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 4191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort n, count; 4201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_FeatureRecord* fr; 4221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( fl->FeatureRecord ) 4251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 4261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod count = fl->FeatureCount; 4271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod fr = fl->FeatureRecord; 4281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod for ( n = 0; n < count; n++ ) 4301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod Free_Feature( &fr[n].Feature ); 4311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( fr ); 4331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 4341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( fl->ApplyOrder ); 4361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 4371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/******************************** 4411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * Lookup List related functions 4421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod ********************************/ 4431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* the subroutines of the following two functions are defined in 4451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod ftxgsub.c and ftxgpos.c respectively */ 4461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* SubTable */ 4491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_Error Load_SubTable( HB_SubTable* st, 4511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Stream stream, 4521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Type table_type, 4531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort lookup_type ) 4541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 4551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( table_type == HB_Type_GSUB ) 4561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return _HB_GSUB_Load_SubTable ( &st->st.gsub, stream, lookup_type ); 4571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod else 4581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return _HB_GPOS_Load_SubTable ( &st->st.gpos, stream, lookup_type ); 4591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 4601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic void Free_SubTable( HB_SubTable* st, 4631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Type table_type, 4641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort lookup_type ) 4651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 4661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( table_type == HB_Type_GSUB ) 4671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod _HB_GSUB_Free_SubTable ( &st->st.gsub, lookup_type ); 4681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod else 4691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod _HB_GPOS_Free_SubTable ( &st->st.gpos, lookup_type ); 4701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 4711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* Lookup */ 4741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_Error Load_Lookup( HB_Lookup* l, 4761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Stream stream, 4771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Type type ) 4781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 4791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Error error; 4801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort n, m, count; 4821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UInt cur_offset, new_offset, base_offset; 4831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_SubTable* st; 4851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Bool is_extension = FALSE; 4871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod base_offset = FILE_Pos(); 4901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ACCESS_Frame( 6L ) ) 4921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 4931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod l->LookupType = GET_UShort(); 4951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod l->LookupFlag = GET_UShort(); 4961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod count = l->SubTableCount = GET_UShort(); 4971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 4981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FORGET_Frame(); 4991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod l->SubTable = NULL; 5011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ALLOC_ARRAY( l->SubTable, count, HB_SubTable ) ) 5031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 5041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod st = l->SubTable; 5061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ( type == HB_Type_GSUB && l->LookupType == HB_GSUB_LOOKUP_EXTENSION ) || 5081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod ( type == HB_Type_GPOS && l->LookupType == HB_GPOS_LOOKUP_EXTENSION ) ) 5091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod is_extension = TRUE; 5101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod for ( n = 0; n < count; n++ ) 5121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 5131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ACCESS_Frame( 2L ) ) 5141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod goto Fail; 5151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod new_offset = GET_UShort() + base_offset; 5171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FORGET_Frame(); 5191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod cur_offset = FILE_Pos(); 5211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( is_extension ) 5231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 5241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( FILE_Seek( new_offset ) || ACCESS_Frame( 8L ) ) 5251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod goto Fail; 5261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if (GET_UShort() != 1) /* format should be 1 */ 5281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod goto Fail; 5291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod l->LookupType = GET_UShort(); 5311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod new_offset += GET_ULong(); 5321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FORGET_Frame(); 5341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 5351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( FILE_Seek( new_offset ) || 5371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod ( error = Load_SubTable( &st[n], stream, 5381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod type, l->LookupType ) ) != HB_Err_Ok ) 5391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod goto Fail; 5401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod (void)FILE_Seek( cur_offset ); 5411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 5421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Ok; 5441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5451512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodFail: 5461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod for ( m = 0; m < n; m++ ) 5471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod Free_SubTable( &st[m], type, l->LookupType ); 5481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( l->SubTable ); 5501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 5511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 5521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic void Free_Lookup( HB_Lookup* l, 5551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Type type) 5561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 5571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort n, count; 5581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_SubTable* st; 5601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( l->SubTable ) 5631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 5641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod count = l->SubTableCount; 5651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod st = l->SubTable; 5661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod for ( n = 0; n < count; n++ ) 5681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod Free_SubTable( &st[n], type, l->LookupType ); 5691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( st ); 5711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 5721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 5731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* LookupList */ 5761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5771512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_INTERNAL HB_Error 5781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod_HB_OPEN_Load_LookupList( HB_LookupList* ll, 5791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Stream stream, 5801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Type type ) 5811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 5821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Error error; 5831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort n, m, count; 5851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UInt cur_offset, new_offset, base_offset; 5861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Lookup* l; 5881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod base_offset = FILE_Pos(); 5911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ACCESS_Frame( 2L ) ) 5931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 5941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod count = ll->LookupCount = GET_UShort(); 5961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FORGET_Frame(); 5981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 5991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod ll->Lookup = NULL; 6001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ALLOC_ARRAY( ll->Lookup, count, HB_Lookup ) ) 6021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 6031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ALLOC_ARRAY( ll->Properties, count, HB_UInt ) ) 6041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod goto Fail2; 6051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod l = ll->Lookup; 6071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod for ( n = 0; n < count; n++ ) 6091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 6101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ACCESS_Frame( 2L ) ) 6111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod goto Fail1; 6121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod new_offset = GET_UShort() + base_offset; 6141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FORGET_Frame(); 6161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod cur_offset = FILE_Pos(); 6181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( FILE_Seek( new_offset ) || 6191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod ( error = Load_Lookup( &l[n], stream, type ) ) != HB_Err_Ok ) 6201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod goto Fail1; 6211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod (void)FILE_Seek( cur_offset ); 6221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 6231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Ok; 6251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6261512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodFail1: 6271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( ll->Properties ); 6281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod for ( m = 0; m < n; m++ ) 6301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod Free_Lookup( &l[m], type ); 6311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6321512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodFail2: 6331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( ll->Lookup ); 6341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 6351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 6361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6381512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_INTERNAL void 6391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod_HB_OPEN_Free_LookupList( HB_LookupList* ll, 6401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Type type ) 6411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 6421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort n, count; 6431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Lookup* l; 6451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( ll->Properties ); 6481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ll->Lookup ) 6501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 6511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod count = ll->LookupCount; 6521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod l = ll->Lookup; 6531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod for ( n = 0; n < count; n++ ) 6551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod Free_Lookup( &l[n], type ); 6561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( l ); 6581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 6591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 6601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/***************************** 6641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * Coverage related functions 6651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod *****************************/ 6661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* CoverageFormat1 */ 6691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_Error Load_Coverage1( HB_CoverageFormat1* cf1, 6711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Stream stream ) 6721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 6731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Error error; 6741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort n, count; 6761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort* ga; 6781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ACCESS_Frame( 2L ) ) 6811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 6821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod count = cf1->GlyphCount = GET_UShort(); 6841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FORGET_Frame(); 6861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod cf1->GlyphArray = NULL; 6881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ALLOC_ARRAY( cf1->GlyphArray, count, HB_UShort ) ) 6901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 6911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod ga = cf1->GlyphArray; 6931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 6941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ACCESS_Frame( count * 2L ) ) 6951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 6961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( cf1->GlyphArray ); 6971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 6981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 6991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod for ( n = 0; n < count; n++ ) 7011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod ga[n] = GET_UShort(); 7021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FORGET_Frame(); 7041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Ok; 7061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 7071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic void Free_Coverage1( HB_CoverageFormat1* cf1) 7101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 7111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( cf1->GlyphArray ); 7121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 7131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* CoverageFormat2 */ 7161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_Error Load_Coverage2( HB_CoverageFormat2* cf2, 7181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Stream stream ) 7191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 7201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Error error; 7211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort n, count; 7231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_RangeRecord* rr; 7251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ACCESS_Frame( 2L ) ) 7281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 7291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod count = cf2->RangeCount = GET_UShort(); 7311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FORGET_Frame(); 7331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod cf2->RangeRecord = NULL; 7351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ALLOC_ARRAY( cf2->RangeRecord, count, HB_RangeRecord ) ) 7371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 7381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod rr = cf2->RangeRecord; 7401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ACCESS_Frame( count * 6L ) ) 7421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod goto Fail; 7431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod for ( n = 0; n < count; n++ ) 7451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 7461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod rr[n].Start = GET_UShort(); 7471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod rr[n].End = GET_UShort(); 7481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod rr[n].StartCoverageIndex = GET_UShort(); 7491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod /* sanity check; we are limited to 16bit integers */ 7511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( rr[n].Start > rr[n].End || 7521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod ( rr[n].End - rr[n].Start + (long)rr[n].StartCoverageIndex ) >= 7531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 0x10000L ) 7541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 7551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod error = ERR(HB_Err_Invalid_SubTable); 7561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod goto Fail; 7571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 7581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 7591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FORGET_Frame(); 7611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Ok; 7631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7641512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodFail: 7651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( cf2->RangeRecord ); 7661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 7671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 7681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic void Free_Coverage2( HB_CoverageFormat2* cf2 ) 7711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 7721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( cf2->RangeRecord ); 7731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 7741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7761512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_INTERNAL HB_Error 7771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod_HB_OPEN_Load_Coverage( HB_Coverage* c, 7781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Stream stream ) 7791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 7801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Error error; 7811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ACCESS_Frame( 2L ) ) 7831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 7841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod c->CoverageFormat = GET_UShort(); 7861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FORGET_Frame(); 7881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod switch ( c->CoverageFormat ) 7901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 7911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod case 1: return Load_Coverage1( &c->cf.cf1, stream ); 7921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod case 2: return Load_Coverage2( &c->cf.cf2, stream ); 7931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod default: return ERR(HB_Err_Invalid_SubTable_Format); 7941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 7951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Ok; /* never reached */ 7971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 7981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 7991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 8001512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_INTERNAL void 8011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod_HB_OPEN_Free_Coverage( HB_Coverage* c ) 8021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 8031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod switch ( c->CoverageFormat ) 8041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 8051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod case 1: Free_Coverage1( &c->cf.cf1 ); break; 8061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod case 2: Free_Coverage2( &c->cf.cf2 ); break; 8071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod default: break; 8081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 8091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 8101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 8111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 8121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_Error Coverage_Index1( HB_CoverageFormat1* cf1, 8131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort glyphID, 8141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort* index ) 8151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 8161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort min, max, new_min, new_max, middle; 8171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 8181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort* array = cf1->GlyphArray; 8191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 8201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 8211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod /* binary search */ 8221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 8231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( cf1->GlyphCount == 0 ) 8241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Not_Covered; 8251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 8261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod new_min = 0; 8271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod new_max = cf1->GlyphCount - 1; 8281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 8291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod do 8301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 8311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod min = new_min; 8321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod max = new_max; 8331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 8341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod /* we use (min + max) / 2 = max - (max - min) / 2 to avoid 8351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod overflow and rounding errors */ 8361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 8371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod middle = max - ( ( max - min ) >> 1 ); 8381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 8391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( glyphID == array[middle] ) 8401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 8411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod *index = middle; 8421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Ok; 8431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 8441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod else if ( glyphID < array[middle] ) 8451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 8461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( middle == min ) 8471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod break; 8481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod new_max = middle - 1; 8491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 8501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod else 8511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 8521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( middle == max ) 8531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod break; 8541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod new_min = middle + 1; 8551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 8561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } while ( min < max ); 8571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 8581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Not_Covered; 8591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 8601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 8611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 8621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_Error Coverage_Index2( HB_CoverageFormat2* cf2, 8631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort glyphID, 8641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort* index ) 8651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 8661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort min, max, new_min, new_max, middle; 8671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 8681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_RangeRecord* rr = cf2->RangeRecord; 8691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 8701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 8711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod /* binary search */ 8721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 8731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( cf2->RangeCount == 0 ) 8741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Not_Covered; 8751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 8761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod new_min = 0; 8771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod new_max = cf2->RangeCount - 1; 8781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 8791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod do 8801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 8811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod min = new_min; 8821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod max = new_max; 8831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 8841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod /* we use (min + max) / 2 = max - (max - min) / 2 to avoid 8851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod overflow and rounding errors */ 8861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 8871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod middle = max - ( ( max - min ) >> 1 ); 8881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 8891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( glyphID >= rr[middle].Start && glyphID <= rr[middle].End ) 8901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 8911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod *index = rr[middle].StartCoverageIndex + glyphID - rr[middle].Start; 8921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Ok; 8931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 8941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod else if ( glyphID < rr[middle].Start ) 8951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 8961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( middle == min ) 8971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod break; 8981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod new_max = middle - 1; 8991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 9001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod else 9011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 9021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( middle == max ) 9031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod break; 9041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod new_min = middle + 1; 9051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 9061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } while ( min < max ); 9071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Not_Covered; 9091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 9101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9121512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_INTERNAL HB_Error 9131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod_HB_OPEN_Coverage_Index( HB_Coverage* c, 9141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort glyphID, 9151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort* index ) 9161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 9171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod switch ( c->CoverageFormat ) 9181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 9191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod case 1: return Coverage_Index1( &c->cf.cf1, glyphID, index ); 9201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod case 2: return Coverage_Index2( &c->cf.cf2, glyphID, index ); 9211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod default: return ERR(HB_Err_Invalid_SubTable_Format); 9221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 9231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Ok; /* never reached */ 9251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 9261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/************************************* 9301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * Class Definition related functions 9311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod *************************************/ 9321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* ClassDefFormat1 */ 9351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_Error Load_ClassDef1( HB_ClassDefinition* cd, 9371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort limit, 9381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Stream stream ) 9391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 9401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Error error; 9411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort n, count; 9431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort* cva; 9451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_ClassDefFormat1* cdf1; 9471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod cdf1 = &cd->cd.cd1; 9501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ACCESS_Frame( 4L ) ) 9521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 9531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod cdf1->StartGlyph = GET_UShort(); 9551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod count = cdf1->GlyphCount = GET_UShort(); 9561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FORGET_Frame(); 9581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod /* sanity check; we are limited to 16bit integers */ 9601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( cdf1->StartGlyph + (long)count >= 0x10000L ) 9621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return ERR(HB_Err_Invalid_SubTable); 9631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod cdf1->ClassValueArray = NULL; 9651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ALLOC_ARRAY( cdf1->ClassValueArray, count, HB_UShort ) ) 9671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 9681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod cva = cdf1->ClassValueArray; 9701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ACCESS_Frame( count * 2L ) ) 9721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod goto Fail; 9731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod for ( n = 0; n < count; n++ ) 9751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 9761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod cva[n] = GET_UShort(); 9771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( cva[n] >= limit ) 9781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 9791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod error = ERR(HB_Err_Invalid_SubTable); 9801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod goto Fail; 9811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 9821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 9831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FORGET_Frame(); 9851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Ok; 9871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9881512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodFail: 9891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( cva ); 9901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 9921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 9931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 9951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic void Free_ClassDef1( HB_ClassDefFormat1* cdf1 ) 9961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 9971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( cdf1->ClassValueArray ); 9981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 9991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* ClassDefFormat2 */ 10021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_Error Load_ClassDef2( HB_ClassDefinition* cd, 10041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort limit, 10051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Stream stream ) 10061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 10071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Error error; 10081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort n, count; 10101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_ClassRangeRecord* crr; 10121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_ClassDefFormat2* cdf2; 10141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod cdf2 = &cd->cd.cd2; 10171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ACCESS_Frame( 2L ) ) 10191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 10201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod count = GET_UShort(); 10221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod cdf2->ClassRangeCount = 0; /* zero for now. we fill with the number of good entries later */ 10231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FORGET_Frame(); 10251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod cdf2->ClassRangeRecord = NULL; 10271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ALLOC_ARRAY( cdf2->ClassRangeRecord, count, HB_ClassRangeRecord ) ) 10291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 10301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod crr = cdf2->ClassRangeRecord; 10321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ACCESS_Frame( count * 6L ) ) 10341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod goto Fail; 10351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod for ( n = 0; n < count; n++ ) 10371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 10381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod crr[n].Start = GET_UShort(); 10391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod crr[n].End = GET_UShort(); 10401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod crr[n].Class = GET_UShort(); 10411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod /* sanity check */ 10431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( crr[n].Start > crr[n].End || 10451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod crr[n].Class >= limit ) 10461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 10471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod /* XXX 10481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * Corrupt entry. Skip it. 10491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * This is hit by Nafees Nastaliq font for example 10501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod */ 10511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod n--; 10521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod count--; 10531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 10541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 10551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FORGET_Frame(); 10571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod cdf2->ClassRangeCount = count; 10591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Ok; 10611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10621512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodFail: 10631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( crr ); 10641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 10661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 10671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic void Free_ClassDef2( HB_ClassDefFormat2* cdf2 ) 10701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 10711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( cdf2->ClassRangeRecord ); 10721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 10731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* ClassDefinition */ 10761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10771512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_INTERNAL HB_Error 10781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod_HB_OPEN_Load_ClassDefinition( HB_ClassDefinition* cd, 10791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort limit, 10801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Stream stream ) 10811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 10821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Error error; 10831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ACCESS_Frame( 2L ) ) 10851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 10861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod cd->ClassFormat = GET_UShort(); 10881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FORGET_Frame(); 10901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod switch ( cd->ClassFormat ) 10921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 10931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod case 1: error = Load_ClassDef1( cd, limit, stream ); break; 10941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod case 2: error = Load_ClassDef2( cd, limit, stream ); break; 10951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod default: error = ERR(HB_Err_Invalid_SubTable_Format); break; 10961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 10971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 10981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( error ) 10991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 11001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 11011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod cd->loaded = TRUE; 11021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 11031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Ok; 11041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 11051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 11061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 11071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_Error 11081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod_HB_OPEN_Load_EmptyClassDefinition( HB_ClassDefinition* cd ) 11091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 11101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Error error; 11111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 11121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod cd->ClassFormat = 1; /* Meaningless */ 11131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 11141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ALLOC_ARRAY( cd->cd.cd1.ClassValueArray, 1, HB_UShort ) ) 11151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 11161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 11171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod cd->loaded = TRUE; 11181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 11191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Ok; 11201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 11211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 11221512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_INTERNAL HB_Error 11231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod_HB_OPEN_Load_EmptyOrClassDefinition( HB_ClassDefinition* cd, 11241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort limit, 11251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UInt class_offset, 11261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UInt base_offset, 11271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Stream stream ) 11281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 11291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Error error; 11301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UInt cur_offset; 11311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 11321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod cur_offset = FILE_Pos(); 11331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 11341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( class_offset ) 11351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 11361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( !FILE_Seek( class_offset + base_offset ) ) 11371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod error = _HB_OPEN_Load_ClassDefinition( cd, limit, stream ); 11381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 11391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod else 11401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod error = _HB_OPEN_Load_EmptyClassDefinition ( cd ); 11411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 11421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if (error == HB_Err_Ok) 11431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod (void)FILE_Seek( cur_offset ); /* Changes error as a side-effect */ 11441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 11451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 11461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 11471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 11481512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_INTERNAL void 11491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod_HB_OPEN_Free_ClassDefinition( HB_ClassDefinition* cd ) 11501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 11511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( !cd->loaded ) 11521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return; 11531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 11541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod switch ( cd->ClassFormat ) 11551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 11561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod case 1: Free_ClassDef1( &cd->cd.cd1 ); break; 11571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod case 2: Free_ClassDef2( &cd->cd.cd2 ); break; 11581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod default: break; 11591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 11601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 11611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 11621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 11631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_Error Get_Class1( HB_ClassDefFormat1* cdf1, 11641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort glyphID, 11651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort* klass, 11661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort* index ) 11671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 11681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort* cva = cdf1->ClassValueArray; 11691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 11701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 11711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( index ) 11721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod *index = 0; 11731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 11741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( glyphID >= cdf1->StartGlyph && 11751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod glyphID < cdf1->StartGlyph + cdf1->GlyphCount ) 11761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 11771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod *klass = cva[glyphID - cdf1->StartGlyph]; 11781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Ok; 11791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 11801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod else 11811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 11821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod *klass = 0; 11831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Not_Covered; 11841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 11851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 11861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 11871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 11881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* we need the index value of the last searched class range record 11891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod in case of failure for constructed GDEF tables */ 11901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 11911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_Error Get_Class2( HB_ClassDefFormat2* cdf2, 11921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort glyphID, 11931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort* klass, 11941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort* index ) 11951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 11961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Error error = HB_Err_Ok; 11971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort min, max, new_min, new_max, middle; 11981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 11991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_ClassRangeRecord* crr = cdf2->ClassRangeRecord; 12001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 12011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 12021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod /* binary search */ 12031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 12041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( cdf2->ClassRangeCount == 0 ) 12051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 12061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod *klass = 0; 12071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( index ) 12081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod *index = 0; 12091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 12101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Not_Covered; 12111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 12121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 12131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod new_min = 0; 12141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod new_max = cdf2->ClassRangeCount - 1; 12151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 12161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod do 12171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 12181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod min = new_min; 12191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod max = new_max; 12201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 12211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod /* we use (min + max) / 2 = max - (max - min) / 2 to avoid 12221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod overflow and rounding errors */ 12231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 12241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod middle = max - ( ( max - min ) >> 1 ); 12251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 12261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( glyphID >= crr[middle].Start && glyphID <= crr[middle].End ) 12271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 12281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod *klass = crr[middle].Class; 12291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod error = HB_Err_Ok; 12301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod break; 12311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 12321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod else if ( glyphID < crr[middle].Start ) 12331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 12341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( middle == min ) 12351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 12361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod *klass = 0; 12371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod error = HB_Err_Not_Covered; 12381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod break; 12391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 12401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod new_max = middle - 1; 12411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 12421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod else 12431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 12441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( middle == max ) 12451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 12461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod *klass = 0; 12471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod error = HB_Err_Not_Covered; 12481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod break; 12491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 12501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod new_min = middle + 1; 12511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 12521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } while ( min < max ); 12531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 12541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( index ) 12551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod *index = middle; 12561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 12571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 12581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 12591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 12601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 12611512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_INTERNAL HB_Error 12621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod_HB_OPEN_Get_Class( HB_ClassDefinition* cd, 12631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort glyphID, 12641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort* klass, 12651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort* index ) 12661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 12671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod switch ( cd->ClassFormat ) 12681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 12691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod case 1: return Get_Class1( &cd->cd.cd1, glyphID, klass, index ); 12701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod case 2: return Get_Class2( &cd->cd.cd2, glyphID, klass, index ); 12711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod default: return ERR(HB_Err_Invalid_SubTable_Format); 12721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 12731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 12741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Ok; /* never reached */ 12751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 12761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 12771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 12781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 12791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/*************************** 12801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * Device related functions 12811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod ***************************/ 12821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 12831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 12841512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_INTERNAL HB_Error 12851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod_HB_OPEN_Load_Device( HB_Device** device, 12861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Stream stream ) 12871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 12881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Device* d; 12891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Error error; 12901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 12911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort n, count; 12921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 12931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort* dv; 12941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 12951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 12961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ACCESS_Frame( 6L ) ) 12971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 12981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 12991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ALLOC( *device, sizeof(HB_Device)) ) 13001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 13011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod *device = 0; 13021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 13031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 13041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 13051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod d = *device; 13061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 13071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod d->StartSize = GET_UShort(); 13081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod d->EndSize = GET_UShort(); 13091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod d->DeltaFormat = GET_UShort(); 13101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 13111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FORGET_Frame(); 13121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 13131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod d->DeltaValue = NULL; 13141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 13151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( d->StartSize > d->EndSize || 13161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod d->DeltaFormat == 0 || d->DeltaFormat > 3 ) 13171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 13181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod /* XXX 13191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * I've seen fontforge generate DeltaFormat == 0. 13201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * Just return Ok and let the NULL DeltaValue disable 13211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * this table. 13221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod */ 13231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Ok; 13241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 13251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 13261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod count = ( ( d->EndSize - d->StartSize + 1 ) >> 13271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod ( 4 - d->DeltaFormat ) ) + 1; 13281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 13291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ALLOC_ARRAY( d->DeltaValue, count, HB_UShort ) ) 13301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 13311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( *device ); 13321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod *device = 0; 13331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 13341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 13351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 13361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( ACCESS_Frame( count * 2L ) ) 13371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 13381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( d->DeltaValue ); 13391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( *device ); 13401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod *device = 0; 13411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return error; 13421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 13431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 13441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod dv = d->DeltaValue; 13451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 13461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod for ( n = 0; n < count; n++ ) 13471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod dv[n] = GET_UShort(); 13481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 13491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FORGET_Frame(); 13501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 13511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Ok; 13521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 13531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 13541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 13551512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_INTERNAL void 13561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod_HB_OPEN_Free_Device( HB_Device* d ) 13571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 13581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( d ) 13591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 13601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( d->DeltaValue ); 13611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod FREE( d ); 13621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 13631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 13641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 13651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 13661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* Since we have the delta values stored in compressed form, we must 13671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod uncompress it now. To simplify the interface, the function always 13681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod returns a meaningful value in `value'; the error is just for 13691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod information. 13701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod | | 13711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod format = 1: 0011223344556677|8899101112131415|... 13721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod | | 13731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod byte 1 byte 2 13741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 13751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 00: (byte >> 14) & mask 13761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 11: (byte >> 12) & mask 13771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod ... 13781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 13791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod mask = 0x0003 13801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod | | 13811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod format = 2: 0000111122223333|4444555566667777|... 13821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod | | 13831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod byte 1 byte 2 13841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 13851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 0000: (byte >> 12) & mask 13861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1111: (byte >> 8) & mask 13871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod ... 13881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 13891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod mask = 0x000F 13901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod | | 13911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod format = 3: 0000000011111111|2222222233333333|... 13921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod | | 13931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod byte 1 byte 2 13941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 13951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 00000000: (byte >> 8) & mask 13961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 11111111: (byte >> 0) & mask 13971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod .... 13981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 13991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod mask = 0x00FF */ 14001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 14011512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_INTERNAL HB_Error 14021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod_HB_OPEN_Get_Device( HB_Device* d, 14031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort size, 14041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Short* value ) 14051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 14061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort byte, bits, mask, s; 14071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 14081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( d && d->DeltaValue && size >= d->StartSize && size <= d->EndSize ) 14091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 14101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_UShort f = d->DeltaFormat; 14111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod s = size - d->StartSize; 14121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod byte = d->DeltaValue[s >> ( 4 - f )]; 14131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod bits = byte >> ( 16 - ( ( s % ( 1 << ( 4 - f ) ) + 1 ) << f ) ); 14141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod mask = 0xFFFF >> ( 16 - ( 1 << f ) ); 14151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 14161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod *value = (HB_Short)( bits & mask ); 14171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 14181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod /* conversion to a signed value */ 14191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 14201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if ( *value >= ( ( mask + 1 ) >> 1 ) ) 14211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod *value -= mask + 1; 14221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 14231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Ok; 14241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 14251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod else 14261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { 14271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod *value = 0; 14281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return HB_Err_Not_Covered; 14291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 14301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 14311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 14321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 14331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* END */ 1434