15569331642446be05292e3e1f8a51218827168cdclaireho/* 25569331642446be05292e3e1f8a51218827168cdclaireho * Copyright (C) 1998-2004 David Turner and Werner Lemberg 35569331642446be05292e3e1f8a51218827168cdclaireho * Copyright (C) 2006 Behdad Esfahbod 45569331642446be05292e3e1f8a51218827168cdclaireho * 55569331642446be05292e3e1f8a51218827168cdclaireho * This is part of HarfBuzz, an OpenType Layout engine library. 65569331642446be05292e3e1f8a51218827168cdclaireho * 75569331642446be05292e3e1f8a51218827168cdclaireho * Permission is hereby granted, without written agreement and without 85569331642446be05292e3e1f8a51218827168cdclaireho * license or royalty fees, to use, copy, modify, and distribute this 95569331642446be05292e3e1f8a51218827168cdclaireho * software and its documentation for any purpose, provided that the 105569331642446be05292e3e1f8a51218827168cdclaireho * above copyright notice and the following two paragraphs appear in 115569331642446be05292e3e1f8a51218827168cdclaireho * all copies of this software. 125569331642446be05292e3e1f8a51218827168cdclaireho * 135569331642446be05292e3e1f8a51218827168cdclaireho * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 145569331642446be05292e3e1f8a51218827168cdclaireho * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 155569331642446be05292e3e1f8a51218827168cdclaireho * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 165569331642446be05292e3e1f8a51218827168cdclaireho * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 175569331642446be05292e3e1f8a51218827168cdclaireho * DAMAGE. 185569331642446be05292e3e1f8a51218827168cdclaireho * 195569331642446be05292e3e1f8a51218827168cdclaireho * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 205569331642446be05292e3e1f8a51218827168cdclaireho * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 215569331642446be05292e3e1f8a51218827168cdclaireho * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 225569331642446be05292e3e1f8a51218827168cdclaireho * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 235569331642446be05292e3e1f8a51218827168cdclaireho * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 245569331642446be05292e3e1f8a51218827168cdclaireho */ 255569331642446be05292e3e1f8a51218827168cdclaireho 265569331642446be05292e3e1f8a51218827168cdclaireho#include "harfbuzz-impl.h" 275569331642446be05292e3e1f8a51218827168cdclaireho#include "harfbuzz-open-private.h" 285569331642446be05292e3e1f8a51218827168cdclaireho 295569331642446be05292e3e1f8a51218827168cdclaireho 305569331642446be05292e3e1f8a51218827168cdclaireho/*************************** 315569331642446be05292e3e1f8a51218827168cdclaireho * Script related functions 325569331642446be05292e3e1f8a51218827168cdclaireho ***************************/ 335569331642446be05292e3e1f8a51218827168cdclaireho 345569331642446be05292e3e1f8a51218827168cdclaireho 355569331642446be05292e3e1f8a51218827168cdclaireho/* LangSys */ 365569331642446be05292e3e1f8a51218827168cdclaireho 375569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_LangSys( HB_LangSys* ls, 385569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 395569331642446be05292e3e1f8a51218827168cdclaireho{ 405569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 415569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 425569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* fi; 435569331642446be05292e3e1f8a51218827168cdclaireho 445569331642446be05292e3e1f8a51218827168cdclaireho 455569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 6L ) ) 465569331642446be05292e3e1f8a51218827168cdclaireho return error; 475569331642446be05292e3e1f8a51218827168cdclaireho 485569331642446be05292e3e1f8a51218827168cdclaireho ls->LookupOrderOffset = GET_UShort(); /* should be 0 */ 495569331642446be05292e3e1f8a51218827168cdclaireho ls->ReqFeatureIndex = GET_UShort(); 505569331642446be05292e3e1f8a51218827168cdclaireho count = ls->FeatureCount = GET_UShort(); 515569331642446be05292e3e1f8a51218827168cdclaireho 525569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 535569331642446be05292e3e1f8a51218827168cdclaireho 545569331642446be05292e3e1f8a51218827168cdclaireho ls->FeatureIndex = NULL; 555569331642446be05292e3e1f8a51218827168cdclaireho 565569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( ls->FeatureIndex, count, HB_UShort ) ) 575569331642446be05292e3e1f8a51218827168cdclaireho return error; 585569331642446be05292e3e1f8a51218827168cdclaireho 595569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 2L ) ) 605569331642446be05292e3e1f8a51218827168cdclaireho { 615569331642446be05292e3e1f8a51218827168cdclaireho FREE( ls->FeatureIndex ); 625569331642446be05292e3e1f8a51218827168cdclaireho return error; 635569331642446be05292e3e1f8a51218827168cdclaireho } 645569331642446be05292e3e1f8a51218827168cdclaireho 655569331642446be05292e3e1f8a51218827168cdclaireho fi = ls->FeatureIndex; 665569331642446be05292e3e1f8a51218827168cdclaireho 675569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 685569331642446be05292e3e1f8a51218827168cdclaireho fi[n] = GET_UShort(); 695569331642446be05292e3e1f8a51218827168cdclaireho 705569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 715569331642446be05292e3e1f8a51218827168cdclaireho 725569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 735569331642446be05292e3e1f8a51218827168cdclaireho} 745569331642446be05292e3e1f8a51218827168cdclaireho 755569331642446be05292e3e1f8a51218827168cdclaireho 765569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_LangSys( HB_LangSys* ls ) 775569331642446be05292e3e1f8a51218827168cdclaireho{ 785569331642446be05292e3e1f8a51218827168cdclaireho FREE( ls->FeatureIndex ); 795569331642446be05292e3e1f8a51218827168cdclaireho} 805569331642446be05292e3e1f8a51218827168cdclaireho 815569331642446be05292e3e1f8a51218827168cdclaireho 825569331642446be05292e3e1f8a51218827168cdclaireho/* Script */ 835569331642446be05292e3e1f8a51218827168cdclaireho 845569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_Script( HB_ScriptTable* s, 855569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 865569331642446be05292e3e1f8a51218827168cdclaireho{ 875569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 885569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, m, count; 895569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 905569331642446be05292e3e1f8a51218827168cdclaireho 915569331642446be05292e3e1f8a51218827168cdclaireho HB_LangSysRecord* lsr; 925569331642446be05292e3e1f8a51218827168cdclaireho 935569331642446be05292e3e1f8a51218827168cdclaireho 945569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 955569331642446be05292e3e1f8a51218827168cdclaireho 965569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 975569331642446be05292e3e1f8a51218827168cdclaireho return error; 985569331642446be05292e3e1f8a51218827168cdclaireho 995569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 1005569331642446be05292e3e1f8a51218827168cdclaireho 1015569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 1025569331642446be05292e3e1f8a51218827168cdclaireho 1035569331642446be05292e3e1f8a51218827168cdclaireho if ( new_offset != base_offset ) /* not a NULL offset */ 1045569331642446be05292e3e1f8a51218827168cdclaireho { 1055569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 1065569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 1075569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_LangSys( &s->DefaultLangSys, 1085569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 1095569331642446be05292e3e1f8a51218827168cdclaireho return error; 1105569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 1115569331642446be05292e3e1f8a51218827168cdclaireho } 1125569331642446be05292e3e1f8a51218827168cdclaireho else 1135569331642446be05292e3e1f8a51218827168cdclaireho { 1145569331642446be05292e3e1f8a51218827168cdclaireho /* we create a DefaultLangSys table with no entries */ 1155569331642446be05292e3e1f8a51218827168cdclaireho 1165569331642446be05292e3e1f8a51218827168cdclaireho s->DefaultLangSys.LookupOrderOffset = 0; 1175569331642446be05292e3e1f8a51218827168cdclaireho s->DefaultLangSys.ReqFeatureIndex = 0xFFFF; 1185569331642446be05292e3e1f8a51218827168cdclaireho s->DefaultLangSys.FeatureCount = 0; 1195569331642446be05292e3e1f8a51218827168cdclaireho s->DefaultLangSys.FeatureIndex = NULL; 1205569331642446be05292e3e1f8a51218827168cdclaireho } 1215569331642446be05292e3e1f8a51218827168cdclaireho 1225569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 1235569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 1245569331642446be05292e3e1f8a51218827168cdclaireho 1255569331642446be05292e3e1f8a51218827168cdclaireho count = s->LangSysCount = GET_UShort(); 1265569331642446be05292e3e1f8a51218827168cdclaireho 1275569331642446be05292e3e1f8a51218827168cdclaireho /* safety check; otherwise the official handling of TrueType Open 1285569331642446be05292e3e1f8a51218827168cdclaireho fonts won't work */ 1295569331642446be05292e3e1f8a51218827168cdclaireho 1305569331642446be05292e3e1f8a51218827168cdclaireho if ( s->LangSysCount == 0 && s->DefaultLangSys.FeatureCount == 0 ) 1315569331642446be05292e3e1f8a51218827168cdclaireho { 1325569331642446be05292e3e1f8a51218827168cdclaireho error = HB_Err_Not_Covered; 1335569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 1345569331642446be05292e3e1f8a51218827168cdclaireho } 1355569331642446be05292e3e1f8a51218827168cdclaireho 1365569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 1375569331642446be05292e3e1f8a51218827168cdclaireho 1385569331642446be05292e3e1f8a51218827168cdclaireho s->LangSysRecord = NULL; 1395569331642446be05292e3e1f8a51218827168cdclaireho 1405569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( s->LangSysRecord, count, HB_LangSysRecord ) ) 1415569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 1425569331642446be05292e3e1f8a51218827168cdclaireho 1435569331642446be05292e3e1f8a51218827168cdclaireho lsr = s->LangSysRecord; 1445569331642446be05292e3e1f8a51218827168cdclaireho 1455569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 1465569331642446be05292e3e1f8a51218827168cdclaireho { 1475569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 6L ) ) 1485569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 1495569331642446be05292e3e1f8a51218827168cdclaireho 1505569331642446be05292e3e1f8a51218827168cdclaireho lsr[n].LangSysTag = GET_ULong(); 1515569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 1525569331642446be05292e3e1f8a51218827168cdclaireho 1535569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 1545569331642446be05292e3e1f8a51218827168cdclaireho 1555569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 1565569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 1575569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_LangSys( &lsr[n].LangSys, stream ) ) != HB_Err_Ok ) 1585569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 1595569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 1605569331642446be05292e3e1f8a51218827168cdclaireho } 1615569331642446be05292e3e1f8a51218827168cdclaireho 1625569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 1635569331642446be05292e3e1f8a51218827168cdclaireho 1645569331642446be05292e3e1f8a51218827168cdclairehoFail1: 1655569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; m++ ) 1665569331642446be05292e3e1f8a51218827168cdclaireho Free_LangSys( &lsr[m].LangSys ); 1675569331642446be05292e3e1f8a51218827168cdclaireho 1685569331642446be05292e3e1f8a51218827168cdclaireho FREE( s->LangSysRecord ); 1695569331642446be05292e3e1f8a51218827168cdclaireho 1705569331642446be05292e3e1f8a51218827168cdclairehoFail2: 1715569331642446be05292e3e1f8a51218827168cdclaireho Free_LangSys( &s->DefaultLangSys ); 1725569331642446be05292e3e1f8a51218827168cdclaireho return error; 1735569331642446be05292e3e1f8a51218827168cdclaireho} 1745569331642446be05292e3e1f8a51218827168cdclaireho 1755569331642446be05292e3e1f8a51218827168cdclaireho 1765569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_Script( HB_ScriptTable* s ) 1775569331642446be05292e3e1f8a51218827168cdclaireho{ 1785569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 1795569331642446be05292e3e1f8a51218827168cdclaireho 1805569331642446be05292e3e1f8a51218827168cdclaireho HB_LangSysRecord* lsr; 1815569331642446be05292e3e1f8a51218827168cdclaireho 1825569331642446be05292e3e1f8a51218827168cdclaireho 1835569331642446be05292e3e1f8a51218827168cdclaireho Free_LangSys( &s->DefaultLangSys ); 1845569331642446be05292e3e1f8a51218827168cdclaireho 1855569331642446be05292e3e1f8a51218827168cdclaireho if ( s->LangSysRecord ) 1865569331642446be05292e3e1f8a51218827168cdclaireho { 1875569331642446be05292e3e1f8a51218827168cdclaireho count = s->LangSysCount; 1885569331642446be05292e3e1f8a51218827168cdclaireho lsr = s->LangSysRecord; 1895569331642446be05292e3e1f8a51218827168cdclaireho 1905569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 1915569331642446be05292e3e1f8a51218827168cdclaireho Free_LangSys( &lsr[n].LangSys ); 1925569331642446be05292e3e1f8a51218827168cdclaireho 1935569331642446be05292e3e1f8a51218827168cdclaireho FREE( lsr ); 1945569331642446be05292e3e1f8a51218827168cdclaireho } 1955569331642446be05292e3e1f8a51218827168cdclaireho} 1965569331642446be05292e3e1f8a51218827168cdclaireho 1975569331642446be05292e3e1f8a51218827168cdclaireho 1985569331642446be05292e3e1f8a51218827168cdclaireho/* ScriptList */ 1995569331642446be05292e3e1f8a51218827168cdclaireho 2005569331642446be05292e3e1f8a51218827168cdclairehoHB_INTERNAL HB_Error 2015569331642446be05292e3e1f8a51218827168cdclaireho_HB_OPEN_Load_ScriptList( HB_ScriptList* sl, 2025569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 2035569331642446be05292e3e1f8a51218827168cdclaireho{ 2045569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 2055569331642446be05292e3e1f8a51218827168cdclaireho 2065569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, script_count; 2075569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 2085569331642446be05292e3e1f8a51218827168cdclaireho 2095569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptRecord* sr; 2105569331642446be05292e3e1f8a51218827168cdclaireho 2115569331642446be05292e3e1f8a51218827168cdclaireho 2125569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 2135569331642446be05292e3e1f8a51218827168cdclaireho 2145569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 2155569331642446be05292e3e1f8a51218827168cdclaireho return error; 2165569331642446be05292e3e1f8a51218827168cdclaireho 2175569331642446be05292e3e1f8a51218827168cdclaireho script_count = GET_UShort(); 2185569331642446be05292e3e1f8a51218827168cdclaireho 2195569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 2205569331642446be05292e3e1f8a51218827168cdclaireho 2215569331642446be05292e3e1f8a51218827168cdclaireho sl->ScriptRecord = NULL; 2225569331642446be05292e3e1f8a51218827168cdclaireho 2235569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( sl->ScriptRecord, script_count, HB_ScriptRecord ) ) 2245569331642446be05292e3e1f8a51218827168cdclaireho return error; 2255569331642446be05292e3e1f8a51218827168cdclaireho 2265569331642446be05292e3e1f8a51218827168cdclaireho sr = sl->ScriptRecord; 2275569331642446be05292e3e1f8a51218827168cdclaireho 2285569331642446be05292e3e1f8a51218827168cdclaireho sl->ScriptCount= 0; 2295569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < script_count; n++ ) 2305569331642446be05292e3e1f8a51218827168cdclaireho { 2315569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 6L ) ) 2325569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 2335569331642446be05292e3e1f8a51218827168cdclaireho 2345569331642446be05292e3e1f8a51218827168cdclaireho sr[sl->ScriptCount].ScriptTag = GET_ULong(); 2355569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 2365569331642446be05292e3e1f8a51218827168cdclaireho 2375569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 2385569331642446be05292e3e1f8a51218827168cdclaireho 2395569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 2405569331642446be05292e3e1f8a51218827168cdclaireho 2415569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) ) 2425569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 2435569331642446be05292e3e1f8a51218827168cdclaireho 2445569331642446be05292e3e1f8a51218827168cdclaireho error = Load_Script( &sr[sl->ScriptCount].Script, stream ); 2455569331642446be05292e3e1f8a51218827168cdclaireho if ( error == HB_Err_Ok ) 2465569331642446be05292e3e1f8a51218827168cdclaireho sl->ScriptCount += 1; 2475569331642446be05292e3e1f8a51218827168cdclaireho else if ( error != HB_Err_Not_Covered ) 2485569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 2495569331642446be05292e3e1f8a51218827168cdclaireho 2505569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 2515569331642446be05292e3e1f8a51218827168cdclaireho } 2525569331642446be05292e3e1f8a51218827168cdclaireho 2535569331642446be05292e3e1f8a51218827168cdclaireho /* Empty tables are harmless and generated by fontforge. 2545569331642446be05292e3e1f8a51218827168cdclaireho * See http://bugzilla.gnome.org/show_bug.cgi?id=347073 2555569331642446be05292e3e1f8a51218827168cdclaireho */ 2565569331642446be05292e3e1f8a51218827168cdclaireho#if 0 2575569331642446be05292e3e1f8a51218827168cdclaireho if ( sl->ScriptCount == 0 ) 2585569331642446be05292e3e1f8a51218827168cdclaireho { 2595569331642446be05292e3e1f8a51218827168cdclaireho error = ERR(HB_Err_Invalid_SubTable); 2605569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 2615569331642446be05292e3e1f8a51218827168cdclaireho } 2625569331642446be05292e3e1f8a51218827168cdclaireho#endif 2635569331642446be05292e3e1f8a51218827168cdclaireho 2645569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 2655569331642446be05292e3e1f8a51218827168cdclaireho 2665569331642446be05292e3e1f8a51218827168cdclairehoFail: 2675569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < sl->ScriptCount; n++ ) 2685569331642446be05292e3e1f8a51218827168cdclaireho Free_Script( &sr[n].Script ); 2695569331642446be05292e3e1f8a51218827168cdclaireho 2705569331642446be05292e3e1f8a51218827168cdclaireho FREE( sl->ScriptRecord ); 2715569331642446be05292e3e1f8a51218827168cdclaireho return error; 2725569331642446be05292e3e1f8a51218827168cdclaireho} 2735569331642446be05292e3e1f8a51218827168cdclaireho 2745569331642446be05292e3e1f8a51218827168cdclaireho 2755569331642446be05292e3e1f8a51218827168cdclairehoHB_INTERNAL void 2765569331642446be05292e3e1f8a51218827168cdclaireho_HB_OPEN_Free_ScriptList( HB_ScriptList* sl ) 2775569331642446be05292e3e1f8a51218827168cdclaireho{ 2785569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 2795569331642446be05292e3e1f8a51218827168cdclaireho 2805569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptRecord* sr; 2815569331642446be05292e3e1f8a51218827168cdclaireho 2825569331642446be05292e3e1f8a51218827168cdclaireho 2835569331642446be05292e3e1f8a51218827168cdclaireho if ( sl->ScriptRecord ) 2845569331642446be05292e3e1f8a51218827168cdclaireho { 2855569331642446be05292e3e1f8a51218827168cdclaireho count = sl->ScriptCount; 2865569331642446be05292e3e1f8a51218827168cdclaireho sr = sl->ScriptRecord; 2875569331642446be05292e3e1f8a51218827168cdclaireho 2885569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 2895569331642446be05292e3e1f8a51218827168cdclaireho Free_Script( &sr[n].Script ); 2905569331642446be05292e3e1f8a51218827168cdclaireho 2915569331642446be05292e3e1f8a51218827168cdclaireho FREE( sr ); 2925569331642446be05292e3e1f8a51218827168cdclaireho } 2935569331642446be05292e3e1f8a51218827168cdclaireho} 2945569331642446be05292e3e1f8a51218827168cdclaireho 2955569331642446be05292e3e1f8a51218827168cdclaireho 2965569331642446be05292e3e1f8a51218827168cdclaireho 2975569331642446be05292e3e1f8a51218827168cdclaireho/********************************* 2985569331642446be05292e3e1f8a51218827168cdclaireho * Feature List related functions 2995569331642446be05292e3e1f8a51218827168cdclaireho *********************************/ 3005569331642446be05292e3e1f8a51218827168cdclaireho 3015569331642446be05292e3e1f8a51218827168cdclaireho 3025569331642446be05292e3e1f8a51218827168cdclaireho/* Feature */ 3035569331642446be05292e3e1f8a51218827168cdclaireho 3045569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_Feature( HB_Feature* f, 3055569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 3065569331642446be05292e3e1f8a51218827168cdclaireho{ 3075569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 3085569331642446be05292e3e1f8a51218827168cdclaireho 3095569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 3105569331642446be05292e3e1f8a51218827168cdclaireho 3115569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* lli; 3125569331642446be05292e3e1f8a51218827168cdclaireho 3135569331642446be05292e3e1f8a51218827168cdclaireho 3145569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 4L ) ) 3155569331642446be05292e3e1f8a51218827168cdclaireho return error; 3165569331642446be05292e3e1f8a51218827168cdclaireho 3175569331642446be05292e3e1f8a51218827168cdclaireho f->FeatureParams = GET_UShort(); /* should be 0 */ 3185569331642446be05292e3e1f8a51218827168cdclaireho count = f->LookupListCount = GET_UShort(); 3195569331642446be05292e3e1f8a51218827168cdclaireho 3205569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 3215569331642446be05292e3e1f8a51218827168cdclaireho 3225569331642446be05292e3e1f8a51218827168cdclaireho f->LookupListIndex = NULL; 3235569331642446be05292e3e1f8a51218827168cdclaireho 3245569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( f->LookupListIndex, count, HB_UShort ) ) 3255569331642446be05292e3e1f8a51218827168cdclaireho return error; 3265569331642446be05292e3e1f8a51218827168cdclaireho 3275569331642446be05292e3e1f8a51218827168cdclaireho lli = f->LookupListIndex; 3285569331642446be05292e3e1f8a51218827168cdclaireho 3295569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 2L ) ) 3305569331642446be05292e3e1f8a51218827168cdclaireho { 3315569331642446be05292e3e1f8a51218827168cdclaireho FREE( f->LookupListIndex ); 3325569331642446be05292e3e1f8a51218827168cdclaireho return error; 3335569331642446be05292e3e1f8a51218827168cdclaireho } 3345569331642446be05292e3e1f8a51218827168cdclaireho 3355569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 3365569331642446be05292e3e1f8a51218827168cdclaireho lli[n] = GET_UShort(); 3375569331642446be05292e3e1f8a51218827168cdclaireho 3385569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 3395569331642446be05292e3e1f8a51218827168cdclaireho 3405569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 3415569331642446be05292e3e1f8a51218827168cdclaireho} 3425569331642446be05292e3e1f8a51218827168cdclaireho 3435569331642446be05292e3e1f8a51218827168cdclaireho 3445569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_Feature( HB_Feature* f ) 3455569331642446be05292e3e1f8a51218827168cdclaireho{ 3465569331642446be05292e3e1f8a51218827168cdclaireho FREE( f->LookupListIndex ); 3475569331642446be05292e3e1f8a51218827168cdclaireho} 3485569331642446be05292e3e1f8a51218827168cdclaireho 3495569331642446be05292e3e1f8a51218827168cdclaireho 3505569331642446be05292e3e1f8a51218827168cdclaireho/* FeatureList */ 3515569331642446be05292e3e1f8a51218827168cdclaireho 3525569331642446be05292e3e1f8a51218827168cdclairehoHB_INTERNAL HB_Error 3535569331642446be05292e3e1f8a51218827168cdclaireho_HB_OPEN_Load_FeatureList( HB_FeatureList* fl, 3545569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 3555569331642446be05292e3e1f8a51218827168cdclaireho{ 3565569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 3575569331642446be05292e3e1f8a51218827168cdclaireho 3585569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, m, count; 3595569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 3605569331642446be05292e3e1f8a51218827168cdclaireho 3615569331642446be05292e3e1f8a51218827168cdclaireho HB_FeatureRecord* fr; 3625569331642446be05292e3e1f8a51218827168cdclaireho 3635569331642446be05292e3e1f8a51218827168cdclaireho 3645569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 3655569331642446be05292e3e1f8a51218827168cdclaireho 3665569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 3675569331642446be05292e3e1f8a51218827168cdclaireho return error; 3685569331642446be05292e3e1f8a51218827168cdclaireho 3695569331642446be05292e3e1f8a51218827168cdclaireho count = fl->FeatureCount = GET_UShort(); 3705569331642446be05292e3e1f8a51218827168cdclaireho 3715569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 3725569331642446be05292e3e1f8a51218827168cdclaireho 3735569331642446be05292e3e1f8a51218827168cdclaireho fl->FeatureRecord = NULL; 3745569331642446be05292e3e1f8a51218827168cdclaireho 3755569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( fl->FeatureRecord, count, HB_FeatureRecord ) ) 3765569331642446be05292e3e1f8a51218827168cdclaireho return error; 3775569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( fl->ApplyOrder, count, HB_UShort ) ) 3785569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 3795569331642446be05292e3e1f8a51218827168cdclaireho 3805569331642446be05292e3e1f8a51218827168cdclaireho fl->ApplyCount = 0; 3815569331642446be05292e3e1f8a51218827168cdclaireho 3825569331642446be05292e3e1f8a51218827168cdclaireho fr = fl->FeatureRecord; 3835569331642446be05292e3e1f8a51218827168cdclaireho 3845569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 3855569331642446be05292e3e1f8a51218827168cdclaireho { 3865569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 6L ) ) 3875569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 3885569331642446be05292e3e1f8a51218827168cdclaireho 3895569331642446be05292e3e1f8a51218827168cdclaireho fr[n].FeatureTag = GET_ULong(); 3905569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 3915569331642446be05292e3e1f8a51218827168cdclaireho 3925569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 3935569331642446be05292e3e1f8a51218827168cdclaireho 3945569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 3955569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 3965569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_Feature( &fr[n].Feature, stream ) ) != HB_Err_Ok ) 3975569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 3985569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 3995569331642446be05292e3e1f8a51218827168cdclaireho } 4005569331642446be05292e3e1f8a51218827168cdclaireho 4015569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 4025569331642446be05292e3e1f8a51218827168cdclaireho 4035569331642446be05292e3e1f8a51218827168cdclairehoFail1: 4045569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; m++ ) 4055569331642446be05292e3e1f8a51218827168cdclaireho Free_Feature( &fr[m].Feature ); 4065569331642446be05292e3e1f8a51218827168cdclaireho 4075569331642446be05292e3e1f8a51218827168cdclaireho FREE( fl->ApplyOrder ); 4085569331642446be05292e3e1f8a51218827168cdclaireho 4095569331642446be05292e3e1f8a51218827168cdclairehoFail2: 4105569331642446be05292e3e1f8a51218827168cdclaireho FREE( fl->FeatureRecord ); 4115569331642446be05292e3e1f8a51218827168cdclaireho 4125569331642446be05292e3e1f8a51218827168cdclaireho return error; 4135569331642446be05292e3e1f8a51218827168cdclaireho} 4145569331642446be05292e3e1f8a51218827168cdclaireho 4155569331642446be05292e3e1f8a51218827168cdclaireho 4165569331642446be05292e3e1f8a51218827168cdclairehoHB_INTERNAL void 4175569331642446be05292e3e1f8a51218827168cdclaireho_HB_OPEN_Free_FeatureList( HB_FeatureList* fl ) 4185569331642446be05292e3e1f8a51218827168cdclaireho{ 4195569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 4205569331642446be05292e3e1f8a51218827168cdclaireho 4215569331642446be05292e3e1f8a51218827168cdclaireho HB_FeatureRecord* fr; 4225569331642446be05292e3e1f8a51218827168cdclaireho 4235569331642446be05292e3e1f8a51218827168cdclaireho 4245569331642446be05292e3e1f8a51218827168cdclaireho if ( fl->FeatureRecord ) 4255569331642446be05292e3e1f8a51218827168cdclaireho { 4265569331642446be05292e3e1f8a51218827168cdclaireho count = fl->FeatureCount; 4275569331642446be05292e3e1f8a51218827168cdclaireho fr = fl->FeatureRecord; 4285569331642446be05292e3e1f8a51218827168cdclaireho 4295569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 4305569331642446be05292e3e1f8a51218827168cdclaireho Free_Feature( &fr[n].Feature ); 4315569331642446be05292e3e1f8a51218827168cdclaireho 4325569331642446be05292e3e1f8a51218827168cdclaireho FREE( fr ); 4335569331642446be05292e3e1f8a51218827168cdclaireho } 4345569331642446be05292e3e1f8a51218827168cdclaireho 4355569331642446be05292e3e1f8a51218827168cdclaireho FREE( fl->ApplyOrder ); 4365569331642446be05292e3e1f8a51218827168cdclaireho} 4375569331642446be05292e3e1f8a51218827168cdclaireho 4385569331642446be05292e3e1f8a51218827168cdclaireho 4395569331642446be05292e3e1f8a51218827168cdclaireho 4405569331642446be05292e3e1f8a51218827168cdclaireho/******************************** 4415569331642446be05292e3e1f8a51218827168cdclaireho * Lookup List related functions 4425569331642446be05292e3e1f8a51218827168cdclaireho ********************************/ 4435569331642446be05292e3e1f8a51218827168cdclaireho 4445569331642446be05292e3e1f8a51218827168cdclaireho/* the subroutines of the following two functions are defined in 4455569331642446be05292e3e1f8a51218827168cdclaireho ftxgsub.c and ftxgpos.c respectively */ 4465569331642446be05292e3e1f8a51218827168cdclaireho 4475569331642446be05292e3e1f8a51218827168cdclaireho 4485569331642446be05292e3e1f8a51218827168cdclaireho/* SubTable */ 4495569331642446be05292e3e1f8a51218827168cdclaireho 4505569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_SubTable( HB_SubTable* st, 4515569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream, 4525569331642446be05292e3e1f8a51218827168cdclaireho HB_Type table_type, 4535569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort lookup_type ) 4545569331642446be05292e3e1f8a51218827168cdclaireho{ 4555569331642446be05292e3e1f8a51218827168cdclaireho if ( table_type == HB_Type_GSUB ) 4565569331642446be05292e3e1f8a51218827168cdclaireho return _HB_GSUB_Load_SubTable ( &st->st.gsub, stream, lookup_type ); 4575569331642446be05292e3e1f8a51218827168cdclaireho else 4585569331642446be05292e3e1f8a51218827168cdclaireho return _HB_GPOS_Load_SubTable ( &st->st.gpos, stream, lookup_type ); 4595569331642446be05292e3e1f8a51218827168cdclaireho} 4605569331642446be05292e3e1f8a51218827168cdclaireho 4615569331642446be05292e3e1f8a51218827168cdclaireho 4625569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_SubTable( HB_SubTable* st, 4635569331642446be05292e3e1f8a51218827168cdclaireho HB_Type table_type, 4645569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort lookup_type ) 4655569331642446be05292e3e1f8a51218827168cdclaireho{ 4665569331642446be05292e3e1f8a51218827168cdclaireho if ( table_type == HB_Type_GSUB ) 4675569331642446be05292e3e1f8a51218827168cdclaireho _HB_GSUB_Free_SubTable ( &st->st.gsub, lookup_type ); 4685569331642446be05292e3e1f8a51218827168cdclaireho else 4695569331642446be05292e3e1f8a51218827168cdclaireho _HB_GPOS_Free_SubTable ( &st->st.gpos, lookup_type ); 4705569331642446be05292e3e1f8a51218827168cdclaireho} 4715569331642446be05292e3e1f8a51218827168cdclaireho 4725569331642446be05292e3e1f8a51218827168cdclaireho 4735569331642446be05292e3e1f8a51218827168cdclaireho/* Lookup */ 4745569331642446be05292e3e1f8a51218827168cdclaireho 4755569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_Lookup( HB_Lookup* l, 4765569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream, 4775569331642446be05292e3e1f8a51218827168cdclaireho HB_Type type ) 4785569331642446be05292e3e1f8a51218827168cdclaireho{ 4795569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 4805569331642446be05292e3e1f8a51218827168cdclaireho 4815569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, m, count; 4825569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 4835569331642446be05292e3e1f8a51218827168cdclaireho 4845569331642446be05292e3e1f8a51218827168cdclaireho HB_SubTable* st; 4855569331642446be05292e3e1f8a51218827168cdclaireho 4865569331642446be05292e3e1f8a51218827168cdclaireho HB_Bool is_extension = FALSE; 4875569331642446be05292e3e1f8a51218827168cdclaireho 4885569331642446be05292e3e1f8a51218827168cdclaireho 4895569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 4905569331642446be05292e3e1f8a51218827168cdclaireho 4915569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 6L ) ) 4925569331642446be05292e3e1f8a51218827168cdclaireho return error; 4935569331642446be05292e3e1f8a51218827168cdclaireho 4945569331642446be05292e3e1f8a51218827168cdclaireho l->LookupType = GET_UShort(); 4955569331642446be05292e3e1f8a51218827168cdclaireho l->LookupFlag = GET_UShort(); 4965569331642446be05292e3e1f8a51218827168cdclaireho count = l->SubTableCount = GET_UShort(); 4975569331642446be05292e3e1f8a51218827168cdclaireho 4985569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 4995569331642446be05292e3e1f8a51218827168cdclaireho 5005569331642446be05292e3e1f8a51218827168cdclaireho l->SubTable = NULL; 5015569331642446be05292e3e1f8a51218827168cdclaireho 5025569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( l->SubTable, count, HB_SubTable ) ) 5035569331642446be05292e3e1f8a51218827168cdclaireho return error; 5045569331642446be05292e3e1f8a51218827168cdclaireho 5055569331642446be05292e3e1f8a51218827168cdclaireho st = l->SubTable; 5065569331642446be05292e3e1f8a51218827168cdclaireho 5075569331642446be05292e3e1f8a51218827168cdclaireho if ( ( type == HB_Type_GSUB && l->LookupType == HB_GSUB_LOOKUP_EXTENSION ) || 5085569331642446be05292e3e1f8a51218827168cdclaireho ( type == HB_Type_GPOS && l->LookupType == HB_GPOS_LOOKUP_EXTENSION ) ) 5095569331642446be05292e3e1f8a51218827168cdclaireho is_extension = TRUE; 5105569331642446be05292e3e1f8a51218827168cdclaireho 5115569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 5125569331642446be05292e3e1f8a51218827168cdclaireho { 5135569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 5145569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 5155569331642446be05292e3e1f8a51218827168cdclaireho 5165569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 5175569331642446be05292e3e1f8a51218827168cdclaireho 5185569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 5195569331642446be05292e3e1f8a51218827168cdclaireho 5205569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 5215569331642446be05292e3e1f8a51218827168cdclaireho 5225569331642446be05292e3e1f8a51218827168cdclaireho if ( is_extension ) 5235569331642446be05292e3e1f8a51218827168cdclaireho { 5245569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || ACCESS_Frame( 8L ) ) 5255569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 5265569331642446be05292e3e1f8a51218827168cdclaireho 5275569331642446be05292e3e1f8a51218827168cdclaireho if (GET_UShort() != 1) /* format should be 1 */ 5285569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 5295569331642446be05292e3e1f8a51218827168cdclaireho 5305569331642446be05292e3e1f8a51218827168cdclaireho l->LookupType = GET_UShort(); 5315569331642446be05292e3e1f8a51218827168cdclaireho new_offset += GET_ULong(); 5325569331642446be05292e3e1f8a51218827168cdclaireho 5335569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 5345569331642446be05292e3e1f8a51218827168cdclaireho } 5355569331642446be05292e3e1f8a51218827168cdclaireho 5365569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 5375569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_SubTable( &st[n], stream, 5385569331642446be05292e3e1f8a51218827168cdclaireho type, l->LookupType ) ) != HB_Err_Ok ) 5395569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 5405569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 5415569331642446be05292e3e1f8a51218827168cdclaireho } 5425569331642446be05292e3e1f8a51218827168cdclaireho 5435569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 5445569331642446be05292e3e1f8a51218827168cdclaireho 5455569331642446be05292e3e1f8a51218827168cdclairehoFail: 5465569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; m++ ) 5475569331642446be05292e3e1f8a51218827168cdclaireho Free_SubTable( &st[m], type, l->LookupType ); 5485569331642446be05292e3e1f8a51218827168cdclaireho 5495569331642446be05292e3e1f8a51218827168cdclaireho FREE( l->SubTable ); 5505569331642446be05292e3e1f8a51218827168cdclaireho return error; 5515569331642446be05292e3e1f8a51218827168cdclaireho} 5525569331642446be05292e3e1f8a51218827168cdclaireho 5535569331642446be05292e3e1f8a51218827168cdclaireho 5545569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_Lookup( HB_Lookup* l, 5555569331642446be05292e3e1f8a51218827168cdclaireho HB_Type type) 5565569331642446be05292e3e1f8a51218827168cdclaireho{ 5575569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 5585569331642446be05292e3e1f8a51218827168cdclaireho 5595569331642446be05292e3e1f8a51218827168cdclaireho HB_SubTable* st; 5605569331642446be05292e3e1f8a51218827168cdclaireho 5615569331642446be05292e3e1f8a51218827168cdclaireho 5625569331642446be05292e3e1f8a51218827168cdclaireho if ( l->SubTable ) 5635569331642446be05292e3e1f8a51218827168cdclaireho { 5645569331642446be05292e3e1f8a51218827168cdclaireho count = l->SubTableCount; 5655569331642446be05292e3e1f8a51218827168cdclaireho st = l->SubTable; 5665569331642446be05292e3e1f8a51218827168cdclaireho 5675569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 5685569331642446be05292e3e1f8a51218827168cdclaireho Free_SubTable( &st[n], type, l->LookupType ); 5695569331642446be05292e3e1f8a51218827168cdclaireho 5705569331642446be05292e3e1f8a51218827168cdclaireho FREE( st ); 5715569331642446be05292e3e1f8a51218827168cdclaireho } 5725569331642446be05292e3e1f8a51218827168cdclaireho} 5735569331642446be05292e3e1f8a51218827168cdclaireho 5745569331642446be05292e3e1f8a51218827168cdclaireho 5755569331642446be05292e3e1f8a51218827168cdclaireho/* LookupList */ 5765569331642446be05292e3e1f8a51218827168cdclaireho 5775569331642446be05292e3e1f8a51218827168cdclairehoHB_INTERNAL HB_Error 5785569331642446be05292e3e1f8a51218827168cdclaireho_HB_OPEN_Load_LookupList( HB_LookupList* ll, 5795569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream, 5805569331642446be05292e3e1f8a51218827168cdclaireho HB_Type type ) 5815569331642446be05292e3e1f8a51218827168cdclaireho{ 5825569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 5835569331642446be05292e3e1f8a51218827168cdclaireho 5845569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, m, count; 5855569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 5865569331642446be05292e3e1f8a51218827168cdclaireho 5875569331642446be05292e3e1f8a51218827168cdclaireho HB_Lookup* l; 5885569331642446be05292e3e1f8a51218827168cdclaireho 5895569331642446be05292e3e1f8a51218827168cdclaireho 5905569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 5915569331642446be05292e3e1f8a51218827168cdclaireho 5925569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 5935569331642446be05292e3e1f8a51218827168cdclaireho return error; 5945569331642446be05292e3e1f8a51218827168cdclaireho 5955569331642446be05292e3e1f8a51218827168cdclaireho count = ll->LookupCount = GET_UShort(); 5965569331642446be05292e3e1f8a51218827168cdclaireho 5975569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 5985569331642446be05292e3e1f8a51218827168cdclaireho 5995569331642446be05292e3e1f8a51218827168cdclaireho ll->Lookup = NULL; 6005569331642446be05292e3e1f8a51218827168cdclaireho 6015569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( ll->Lookup, count, HB_Lookup ) ) 6025569331642446be05292e3e1f8a51218827168cdclaireho return error; 6035569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( ll->Properties, count, HB_UInt ) ) 6045569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 6055569331642446be05292e3e1f8a51218827168cdclaireho 6065569331642446be05292e3e1f8a51218827168cdclaireho l = ll->Lookup; 6075569331642446be05292e3e1f8a51218827168cdclaireho 6085569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 6095569331642446be05292e3e1f8a51218827168cdclaireho { 6105569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 6115569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 6125569331642446be05292e3e1f8a51218827168cdclaireho 6135569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 6145569331642446be05292e3e1f8a51218827168cdclaireho 6155569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 6165569331642446be05292e3e1f8a51218827168cdclaireho 6175569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 6185569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 6195569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_Lookup( &l[n], stream, type ) ) != HB_Err_Ok ) 6205569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 6215569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 6225569331642446be05292e3e1f8a51218827168cdclaireho } 6235569331642446be05292e3e1f8a51218827168cdclaireho 6245569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 6255569331642446be05292e3e1f8a51218827168cdclaireho 6265569331642446be05292e3e1f8a51218827168cdclairehoFail1: 6275569331642446be05292e3e1f8a51218827168cdclaireho FREE( ll->Properties ); 6285569331642446be05292e3e1f8a51218827168cdclaireho 6295569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; m++ ) 6305569331642446be05292e3e1f8a51218827168cdclaireho Free_Lookup( &l[m], type ); 6315569331642446be05292e3e1f8a51218827168cdclaireho 6325569331642446be05292e3e1f8a51218827168cdclairehoFail2: 6335569331642446be05292e3e1f8a51218827168cdclaireho FREE( ll->Lookup ); 6345569331642446be05292e3e1f8a51218827168cdclaireho return error; 6355569331642446be05292e3e1f8a51218827168cdclaireho} 6365569331642446be05292e3e1f8a51218827168cdclaireho 6375569331642446be05292e3e1f8a51218827168cdclaireho 6385569331642446be05292e3e1f8a51218827168cdclairehoHB_INTERNAL void 6395569331642446be05292e3e1f8a51218827168cdclaireho_HB_OPEN_Free_LookupList( HB_LookupList* ll, 6405569331642446be05292e3e1f8a51218827168cdclaireho HB_Type type ) 6415569331642446be05292e3e1f8a51218827168cdclaireho{ 6425569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 6435569331642446be05292e3e1f8a51218827168cdclaireho 6445569331642446be05292e3e1f8a51218827168cdclaireho HB_Lookup* l; 6455569331642446be05292e3e1f8a51218827168cdclaireho 6465569331642446be05292e3e1f8a51218827168cdclaireho 6475569331642446be05292e3e1f8a51218827168cdclaireho FREE( ll->Properties ); 6485569331642446be05292e3e1f8a51218827168cdclaireho 6495569331642446be05292e3e1f8a51218827168cdclaireho if ( ll->Lookup ) 6505569331642446be05292e3e1f8a51218827168cdclaireho { 6515569331642446be05292e3e1f8a51218827168cdclaireho count = ll->LookupCount; 6525569331642446be05292e3e1f8a51218827168cdclaireho l = ll->Lookup; 6535569331642446be05292e3e1f8a51218827168cdclaireho 6545569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 6555569331642446be05292e3e1f8a51218827168cdclaireho Free_Lookup( &l[n], type ); 6565569331642446be05292e3e1f8a51218827168cdclaireho 6575569331642446be05292e3e1f8a51218827168cdclaireho FREE( l ); 6585569331642446be05292e3e1f8a51218827168cdclaireho } 6595569331642446be05292e3e1f8a51218827168cdclaireho} 6605569331642446be05292e3e1f8a51218827168cdclaireho 6615569331642446be05292e3e1f8a51218827168cdclaireho 6625569331642446be05292e3e1f8a51218827168cdclaireho 6635569331642446be05292e3e1f8a51218827168cdclaireho/***************************** 6645569331642446be05292e3e1f8a51218827168cdclaireho * Coverage related functions 6655569331642446be05292e3e1f8a51218827168cdclaireho *****************************/ 6665569331642446be05292e3e1f8a51218827168cdclaireho 6675569331642446be05292e3e1f8a51218827168cdclaireho 6685569331642446be05292e3e1f8a51218827168cdclaireho/* CoverageFormat1 */ 6695569331642446be05292e3e1f8a51218827168cdclaireho 6705569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_Coverage1( HB_CoverageFormat1* cf1, 6715569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 6725569331642446be05292e3e1f8a51218827168cdclaireho{ 6735569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 6745569331642446be05292e3e1f8a51218827168cdclaireho 6755569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 6765569331642446be05292e3e1f8a51218827168cdclaireho 6775569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* ga; 6785569331642446be05292e3e1f8a51218827168cdclaireho 6795569331642446be05292e3e1f8a51218827168cdclaireho 6805569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 6815569331642446be05292e3e1f8a51218827168cdclaireho return error; 6825569331642446be05292e3e1f8a51218827168cdclaireho 6835569331642446be05292e3e1f8a51218827168cdclaireho count = cf1->GlyphCount = GET_UShort(); 6845569331642446be05292e3e1f8a51218827168cdclaireho 6855569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 6865569331642446be05292e3e1f8a51218827168cdclaireho 6875569331642446be05292e3e1f8a51218827168cdclaireho cf1->GlyphArray = NULL; 6885569331642446be05292e3e1f8a51218827168cdclaireho 6895569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( cf1->GlyphArray, count, HB_UShort ) ) 6905569331642446be05292e3e1f8a51218827168cdclaireho return error; 6915569331642446be05292e3e1f8a51218827168cdclaireho 6925569331642446be05292e3e1f8a51218827168cdclaireho ga = cf1->GlyphArray; 6935569331642446be05292e3e1f8a51218827168cdclaireho 6945569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 2L ) ) 6955569331642446be05292e3e1f8a51218827168cdclaireho { 6965569331642446be05292e3e1f8a51218827168cdclaireho FREE( cf1->GlyphArray ); 6975569331642446be05292e3e1f8a51218827168cdclaireho return error; 6985569331642446be05292e3e1f8a51218827168cdclaireho } 6995569331642446be05292e3e1f8a51218827168cdclaireho 7005569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 7015569331642446be05292e3e1f8a51218827168cdclaireho ga[n] = GET_UShort(); 7025569331642446be05292e3e1f8a51218827168cdclaireho 7035569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 7045569331642446be05292e3e1f8a51218827168cdclaireho 7055569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 7065569331642446be05292e3e1f8a51218827168cdclaireho} 7075569331642446be05292e3e1f8a51218827168cdclaireho 7085569331642446be05292e3e1f8a51218827168cdclaireho 7095569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_Coverage1( HB_CoverageFormat1* cf1) 7105569331642446be05292e3e1f8a51218827168cdclaireho{ 7115569331642446be05292e3e1f8a51218827168cdclaireho FREE( cf1->GlyphArray ); 7125569331642446be05292e3e1f8a51218827168cdclaireho} 7135569331642446be05292e3e1f8a51218827168cdclaireho 7145569331642446be05292e3e1f8a51218827168cdclaireho 7155569331642446be05292e3e1f8a51218827168cdclaireho/* CoverageFormat2 */ 7165569331642446be05292e3e1f8a51218827168cdclaireho 7175569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_Coverage2( HB_CoverageFormat2* cf2, 7185569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 7195569331642446be05292e3e1f8a51218827168cdclaireho{ 7205569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 7215569331642446be05292e3e1f8a51218827168cdclaireho 7225569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 7235569331642446be05292e3e1f8a51218827168cdclaireho 7245569331642446be05292e3e1f8a51218827168cdclaireho HB_RangeRecord* rr; 7255569331642446be05292e3e1f8a51218827168cdclaireho 7265569331642446be05292e3e1f8a51218827168cdclaireho 7275569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 7285569331642446be05292e3e1f8a51218827168cdclaireho return error; 7295569331642446be05292e3e1f8a51218827168cdclaireho 7305569331642446be05292e3e1f8a51218827168cdclaireho count = cf2->RangeCount = GET_UShort(); 7315569331642446be05292e3e1f8a51218827168cdclaireho 7325569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 7335569331642446be05292e3e1f8a51218827168cdclaireho 7345569331642446be05292e3e1f8a51218827168cdclaireho cf2->RangeRecord = NULL; 7355569331642446be05292e3e1f8a51218827168cdclaireho 7365569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( cf2->RangeRecord, count, HB_RangeRecord ) ) 7375569331642446be05292e3e1f8a51218827168cdclaireho return error; 7385569331642446be05292e3e1f8a51218827168cdclaireho 7395569331642446be05292e3e1f8a51218827168cdclaireho rr = cf2->RangeRecord; 7405569331642446be05292e3e1f8a51218827168cdclaireho 7415569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 6L ) ) 7425569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 7435569331642446be05292e3e1f8a51218827168cdclaireho 7445569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 7455569331642446be05292e3e1f8a51218827168cdclaireho { 7465569331642446be05292e3e1f8a51218827168cdclaireho rr[n].Start = GET_UShort(); 7475569331642446be05292e3e1f8a51218827168cdclaireho rr[n].End = GET_UShort(); 7485569331642446be05292e3e1f8a51218827168cdclaireho rr[n].StartCoverageIndex = GET_UShort(); 7495569331642446be05292e3e1f8a51218827168cdclaireho 7505569331642446be05292e3e1f8a51218827168cdclaireho /* sanity check; we are limited to 16bit integers */ 7515569331642446be05292e3e1f8a51218827168cdclaireho if ( rr[n].Start > rr[n].End || 7525569331642446be05292e3e1f8a51218827168cdclaireho ( rr[n].End - rr[n].Start + (long)rr[n].StartCoverageIndex ) >= 7535569331642446be05292e3e1f8a51218827168cdclaireho 0x10000L ) 7545569331642446be05292e3e1f8a51218827168cdclaireho { 7555569331642446be05292e3e1f8a51218827168cdclaireho error = ERR(HB_Err_Invalid_SubTable); 7565569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 7575569331642446be05292e3e1f8a51218827168cdclaireho } 7585569331642446be05292e3e1f8a51218827168cdclaireho } 7595569331642446be05292e3e1f8a51218827168cdclaireho 7605569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 7615569331642446be05292e3e1f8a51218827168cdclaireho 7625569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 7635569331642446be05292e3e1f8a51218827168cdclaireho 7645569331642446be05292e3e1f8a51218827168cdclairehoFail: 7655569331642446be05292e3e1f8a51218827168cdclaireho FREE( cf2->RangeRecord ); 7665569331642446be05292e3e1f8a51218827168cdclaireho return error; 7675569331642446be05292e3e1f8a51218827168cdclaireho} 7685569331642446be05292e3e1f8a51218827168cdclaireho 7695569331642446be05292e3e1f8a51218827168cdclaireho 7705569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_Coverage2( HB_CoverageFormat2* cf2 ) 7715569331642446be05292e3e1f8a51218827168cdclaireho{ 7725569331642446be05292e3e1f8a51218827168cdclaireho FREE( cf2->RangeRecord ); 7735569331642446be05292e3e1f8a51218827168cdclaireho} 7745569331642446be05292e3e1f8a51218827168cdclaireho 7755569331642446be05292e3e1f8a51218827168cdclaireho 7765569331642446be05292e3e1f8a51218827168cdclairehoHB_INTERNAL HB_Error 7775569331642446be05292e3e1f8a51218827168cdclaireho_HB_OPEN_Load_Coverage( HB_Coverage* c, 7785569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 7795569331642446be05292e3e1f8a51218827168cdclaireho{ 7805569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 7815569331642446be05292e3e1f8a51218827168cdclaireho 7825569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 7835569331642446be05292e3e1f8a51218827168cdclaireho return error; 7845569331642446be05292e3e1f8a51218827168cdclaireho 7855569331642446be05292e3e1f8a51218827168cdclaireho c->CoverageFormat = GET_UShort(); 7865569331642446be05292e3e1f8a51218827168cdclaireho 7875569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 7885569331642446be05292e3e1f8a51218827168cdclaireho 7895569331642446be05292e3e1f8a51218827168cdclaireho switch ( c->CoverageFormat ) 7905569331642446be05292e3e1f8a51218827168cdclaireho { 7915569331642446be05292e3e1f8a51218827168cdclaireho case 1: return Load_Coverage1( &c->cf.cf1, stream ); 7925569331642446be05292e3e1f8a51218827168cdclaireho case 2: return Load_Coverage2( &c->cf.cf2, stream ); 7935569331642446be05292e3e1f8a51218827168cdclaireho default: return ERR(HB_Err_Invalid_SubTable_Format); 7945569331642446be05292e3e1f8a51218827168cdclaireho } 7955569331642446be05292e3e1f8a51218827168cdclaireho 7965569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; /* never reached */ 7975569331642446be05292e3e1f8a51218827168cdclaireho} 7985569331642446be05292e3e1f8a51218827168cdclaireho 7995569331642446be05292e3e1f8a51218827168cdclaireho 8005569331642446be05292e3e1f8a51218827168cdclairehoHB_INTERNAL void 8015569331642446be05292e3e1f8a51218827168cdclaireho_HB_OPEN_Free_Coverage( HB_Coverage* c ) 8025569331642446be05292e3e1f8a51218827168cdclaireho{ 8035569331642446be05292e3e1f8a51218827168cdclaireho switch ( c->CoverageFormat ) 8045569331642446be05292e3e1f8a51218827168cdclaireho { 8055569331642446be05292e3e1f8a51218827168cdclaireho case 1: Free_Coverage1( &c->cf.cf1 ); break; 8065569331642446be05292e3e1f8a51218827168cdclaireho case 2: Free_Coverage2( &c->cf.cf2 ); break; 8075569331642446be05292e3e1f8a51218827168cdclaireho default: break; 8085569331642446be05292e3e1f8a51218827168cdclaireho } 8095569331642446be05292e3e1f8a51218827168cdclaireho} 8105569331642446be05292e3e1f8a51218827168cdclaireho 8115569331642446be05292e3e1f8a51218827168cdclaireho 8125569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Coverage_Index1( HB_CoverageFormat1* cf1, 8135569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort glyphID, 8145569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* index ) 8155569331642446be05292e3e1f8a51218827168cdclaireho{ 8165569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort min, max, new_min, new_max, middle; 8175569331642446be05292e3e1f8a51218827168cdclaireho 8185569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* array = cf1->GlyphArray; 8195569331642446be05292e3e1f8a51218827168cdclaireho 8205569331642446be05292e3e1f8a51218827168cdclaireho 8215569331642446be05292e3e1f8a51218827168cdclaireho /* binary search */ 8225569331642446be05292e3e1f8a51218827168cdclaireho 8235569331642446be05292e3e1f8a51218827168cdclaireho if ( cf1->GlyphCount == 0 ) 8245569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 8255569331642446be05292e3e1f8a51218827168cdclaireho 8265569331642446be05292e3e1f8a51218827168cdclaireho new_min = 0; 8275569331642446be05292e3e1f8a51218827168cdclaireho new_max = cf1->GlyphCount - 1; 8285569331642446be05292e3e1f8a51218827168cdclaireho 8295569331642446be05292e3e1f8a51218827168cdclaireho do 8305569331642446be05292e3e1f8a51218827168cdclaireho { 8315569331642446be05292e3e1f8a51218827168cdclaireho min = new_min; 8325569331642446be05292e3e1f8a51218827168cdclaireho max = new_max; 8335569331642446be05292e3e1f8a51218827168cdclaireho 8345569331642446be05292e3e1f8a51218827168cdclaireho /* we use (min + max) / 2 = max - (max - min) / 2 to avoid 8355569331642446be05292e3e1f8a51218827168cdclaireho overflow and rounding errors */ 8365569331642446be05292e3e1f8a51218827168cdclaireho 8375569331642446be05292e3e1f8a51218827168cdclaireho middle = max - ( ( max - min ) >> 1 ); 8385569331642446be05292e3e1f8a51218827168cdclaireho 8395569331642446be05292e3e1f8a51218827168cdclaireho if ( glyphID == array[middle] ) 8405569331642446be05292e3e1f8a51218827168cdclaireho { 8415569331642446be05292e3e1f8a51218827168cdclaireho *index = middle; 8425569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 8435569331642446be05292e3e1f8a51218827168cdclaireho } 8445569331642446be05292e3e1f8a51218827168cdclaireho else if ( glyphID < array[middle] ) 8455569331642446be05292e3e1f8a51218827168cdclaireho { 8465569331642446be05292e3e1f8a51218827168cdclaireho if ( middle == min ) 8475569331642446be05292e3e1f8a51218827168cdclaireho break; 8485569331642446be05292e3e1f8a51218827168cdclaireho new_max = middle - 1; 8495569331642446be05292e3e1f8a51218827168cdclaireho } 8505569331642446be05292e3e1f8a51218827168cdclaireho else 8515569331642446be05292e3e1f8a51218827168cdclaireho { 8525569331642446be05292e3e1f8a51218827168cdclaireho if ( middle == max ) 8535569331642446be05292e3e1f8a51218827168cdclaireho break; 8545569331642446be05292e3e1f8a51218827168cdclaireho new_min = middle + 1; 8555569331642446be05292e3e1f8a51218827168cdclaireho } 8565569331642446be05292e3e1f8a51218827168cdclaireho } while ( min < max ); 8575569331642446be05292e3e1f8a51218827168cdclaireho 8585569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 8595569331642446be05292e3e1f8a51218827168cdclaireho} 8605569331642446be05292e3e1f8a51218827168cdclaireho 8615569331642446be05292e3e1f8a51218827168cdclaireho 8625569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Coverage_Index2( HB_CoverageFormat2* cf2, 8635569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort glyphID, 8645569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* index ) 8655569331642446be05292e3e1f8a51218827168cdclaireho{ 8665569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort min, max, new_min, new_max, middle; 8675569331642446be05292e3e1f8a51218827168cdclaireho 8685569331642446be05292e3e1f8a51218827168cdclaireho HB_RangeRecord* rr = cf2->RangeRecord; 8695569331642446be05292e3e1f8a51218827168cdclaireho 8705569331642446be05292e3e1f8a51218827168cdclaireho 8715569331642446be05292e3e1f8a51218827168cdclaireho /* binary search */ 8725569331642446be05292e3e1f8a51218827168cdclaireho 8735569331642446be05292e3e1f8a51218827168cdclaireho if ( cf2->RangeCount == 0 ) 8745569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 8755569331642446be05292e3e1f8a51218827168cdclaireho 8765569331642446be05292e3e1f8a51218827168cdclaireho new_min = 0; 8775569331642446be05292e3e1f8a51218827168cdclaireho new_max = cf2->RangeCount - 1; 8785569331642446be05292e3e1f8a51218827168cdclaireho 8795569331642446be05292e3e1f8a51218827168cdclaireho do 8805569331642446be05292e3e1f8a51218827168cdclaireho { 8815569331642446be05292e3e1f8a51218827168cdclaireho min = new_min; 8825569331642446be05292e3e1f8a51218827168cdclaireho max = new_max; 8835569331642446be05292e3e1f8a51218827168cdclaireho 8845569331642446be05292e3e1f8a51218827168cdclaireho /* we use (min + max) / 2 = max - (max - min) / 2 to avoid 8855569331642446be05292e3e1f8a51218827168cdclaireho overflow and rounding errors */ 8865569331642446be05292e3e1f8a51218827168cdclaireho 8875569331642446be05292e3e1f8a51218827168cdclaireho middle = max - ( ( max - min ) >> 1 ); 8885569331642446be05292e3e1f8a51218827168cdclaireho 8895569331642446be05292e3e1f8a51218827168cdclaireho if ( glyphID >= rr[middle].Start && glyphID <= rr[middle].End ) 8905569331642446be05292e3e1f8a51218827168cdclaireho { 8915569331642446be05292e3e1f8a51218827168cdclaireho *index = rr[middle].StartCoverageIndex + glyphID - rr[middle].Start; 8925569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 8935569331642446be05292e3e1f8a51218827168cdclaireho } 8945569331642446be05292e3e1f8a51218827168cdclaireho else if ( glyphID < rr[middle].Start ) 8955569331642446be05292e3e1f8a51218827168cdclaireho { 8965569331642446be05292e3e1f8a51218827168cdclaireho if ( middle == min ) 8975569331642446be05292e3e1f8a51218827168cdclaireho break; 8985569331642446be05292e3e1f8a51218827168cdclaireho new_max = middle - 1; 8995569331642446be05292e3e1f8a51218827168cdclaireho } 9005569331642446be05292e3e1f8a51218827168cdclaireho else 9015569331642446be05292e3e1f8a51218827168cdclaireho { 9025569331642446be05292e3e1f8a51218827168cdclaireho if ( middle == max ) 9035569331642446be05292e3e1f8a51218827168cdclaireho break; 9045569331642446be05292e3e1f8a51218827168cdclaireho new_min = middle + 1; 9055569331642446be05292e3e1f8a51218827168cdclaireho } 9065569331642446be05292e3e1f8a51218827168cdclaireho } while ( min < max ); 9075569331642446be05292e3e1f8a51218827168cdclaireho 9085569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 9095569331642446be05292e3e1f8a51218827168cdclaireho} 9105569331642446be05292e3e1f8a51218827168cdclaireho 9115569331642446be05292e3e1f8a51218827168cdclaireho 9125569331642446be05292e3e1f8a51218827168cdclairehoHB_INTERNAL HB_Error 9135569331642446be05292e3e1f8a51218827168cdclaireho_HB_OPEN_Coverage_Index( HB_Coverage* c, 9145569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort glyphID, 9155569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* index ) 9165569331642446be05292e3e1f8a51218827168cdclaireho{ 9175569331642446be05292e3e1f8a51218827168cdclaireho switch ( c->CoverageFormat ) 9185569331642446be05292e3e1f8a51218827168cdclaireho { 9195569331642446be05292e3e1f8a51218827168cdclaireho case 1: return Coverage_Index1( &c->cf.cf1, glyphID, index ); 9205569331642446be05292e3e1f8a51218827168cdclaireho case 2: return Coverage_Index2( &c->cf.cf2, glyphID, index ); 9215569331642446be05292e3e1f8a51218827168cdclaireho default: return ERR(HB_Err_Invalid_SubTable_Format); 9225569331642446be05292e3e1f8a51218827168cdclaireho } 9235569331642446be05292e3e1f8a51218827168cdclaireho 9245569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; /* never reached */ 9255569331642446be05292e3e1f8a51218827168cdclaireho} 9265569331642446be05292e3e1f8a51218827168cdclaireho 9275569331642446be05292e3e1f8a51218827168cdclaireho 9285569331642446be05292e3e1f8a51218827168cdclaireho 9295569331642446be05292e3e1f8a51218827168cdclaireho/************************************* 9305569331642446be05292e3e1f8a51218827168cdclaireho * Class Definition related functions 9315569331642446be05292e3e1f8a51218827168cdclaireho *************************************/ 9325569331642446be05292e3e1f8a51218827168cdclaireho 9335569331642446be05292e3e1f8a51218827168cdclaireho 9345569331642446be05292e3e1f8a51218827168cdclaireho/* ClassDefFormat1 */ 9355569331642446be05292e3e1f8a51218827168cdclaireho 9365569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_ClassDef1( HB_ClassDefinition* cd, 9375569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort limit, 9385569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 9395569331642446be05292e3e1f8a51218827168cdclaireho{ 9405569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 9415569331642446be05292e3e1f8a51218827168cdclaireho 9425569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 9435569331642446be05292e3e1f8a51218827168cdclaireho 9445569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* cva; 9455569331642446be05292e3e1f8a51218827168cdclaireho 9465569331642446be05292e3e1f8a51218827168cdclaireho HB_ClassDefFormat1* cdf1; 9475569331642446be05292e3e1f8a51218827168cdclaireho 9485569331642446be05292e3e1f8a51218827168cdclaireho 9495569331642446be05292e3e1f8a51218827168cdclaireho cdf1 = &cd->cd.cd1; 9505569331642446be05292e3e1f8a51218827168cdclaireho 9515569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 4L ) ) 9525569331642446be05292e3e1f8a51218827168cdclaireho return error; 9535569331642446be05292e3e1f8a51218827168cdclaireho 9545569331642446be05292e3e1f8a51218827168cdclaireho cdf1->StartGlyph = GET_UShort(); 9555569331642446be05292e3e1f8a51218827168cdclaireho count = cdf1->GlyphCount = GET_UShort(); 9565569331642446be05292e3e1f8a51218827168cdclaireho 9575569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 9585569331642446be05292e3e1f8a51218827168cdclaireho 9595569331642446be05292e3e1f8a51218827168cdclaireho /* sanity check; we are limited to 16bit integers */ 9605569331642446be05292e3e1f8a51218827168cdclaireho 9615569331642446be05292e3e1f8a51218827168cdclaireho if ( cdf1->StartGlyph + (long)count >= 0x10000L ) 9625569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable); 9635569331642446be05292e3e1f8a51218827168cdclaireho 9645569331642446be05292e3e1f8a51218827168cdclaireho cdf1->ClassValueArray = NULL; 9655569331642446be05292e3e1f8a51218827168cdclaireho 9665569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( cdf1->ClassValueArray, count, HB_UShort ) ) 9675569331642446be05292e3e1f8a51218827168cdclaireho return error; 9685569331642446be05292e3e1f8a51218827168cdclaireho 9695569331642446be05292e3e1f8a51218827168cdclaireho cva = cdf1->ClassValueArray; 9705569331642446be05292e3e1f8a51218827168cdclaireho 9715569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 2L ) ) 9725569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 9735569331642446be05292e3e1f8a51218827168cdclaireho 9745569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 9755569331642446be05292e3e1f8a51218827168cdclaireho { 9765569331642446be05292e3e1f8a51218827168cdclaireho cva[n] = GET_UShort(); 9775569331642446be05292e3e1f8a51218827168cdclaireho if ( cva[n] >= limit ) 9785569331642446be05292e3e1f8a51218827168cdclaireho { 9795569331642446be05292e3e1f8a51218827168cdclaireho error = ERR(HB_Err_Invalid_SubTable); 9805569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 9815569331642446be05292e3e1f8a51218827168cdclaireho } 9825569331642446be05292e3e1f8a51218827168cdclaireho } 9835569331642446be05292e3e1f8a51218827168cdclaireho 9845569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 9855569331642446be05292e3e1f8a51218827168cdclaireho 9865569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 9875569331642446be05292e3e1f8a51218827168cdclaireho 9885569331642446be05292e3e1f8a51218827168cdclairehoFail: 9895569331642446be05292e3e1f8a51218827168cdclaireho FREE( cva ); 9905569331642446be05292e3e1f8a51218827168cdclaireho 9915569331642446be05292e3e1f8a51218827168cdclaireho return error; 9925569331642446be05292e3e1f8a51218827168cdclaireho} 9935569331642446be05292e3e1f8a51218827168cdclaireho 9945569331642446be05292e3e1f8a51218827168cdclaireho 9955569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_ClassDef1( HB_ClassDefFormat1* cdf1 ) 9965569331642446be05292e3e1f8a51218827168cdclaireho{ 9975569331642446be05292e3e1f8a51218827168cdclaireho FREE( cdf1->ClassValueArray ); 9985569331642446be05292e3e1f8a51218827168cdclaireho} 9995569331642446be05292e3e1f8a51218827168cdclaireho 10005569331642446be05292e3e1f8a51218827168cdclaireho 10015569331642446be05292e3e1f8a51218827168cdclaireho/* ClassDefFormat2 */ 10025569331642446be05292e3e1f8a51218827168cdclaireho 10035569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_ClassDef2( HB_ClassDefinition* cd, 10045569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort limit, 10055569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 10065569331642446be05292e3e1f8a51218827168cdclaireho{ 10075569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 10085569331642446be05292e3e1f8a51218827168cdclaireho 10095569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 10105569331642446be05292e3e1f8a51218827168cdclaireho 10115569331642446be05292e3e1f8a51218827168cdclaireho HB_ClassRangeRecord* crr; 10125569331642446be05292e3e1f8a51218827168cdclaireho 10135569331642446be05292e3e1f8a51218827168cdclaireho HB_ClassDefFormat2* cdf2; 10145569331642446be05292e3e1f8a51218827168cdclaireho 10155569331642446be05292e3e1f8a51218827168cdclaireho 10165569331642446be05292e3e1f8a51218827168cdclaireho cdf2 = &cd->cd.cd2; 10175569331642446be05292e3e1f8a51218827168cdclaireho 10185569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 10195569331642446be05292e3e1f8a51218827168cdclaireho return error; 10205569331642446be05292e3e1f8a51218827168cdclaireho 10215569331642446be05292e3e1f8a51218827168cdclaireho count = GET_UShort(); 10225569331642446be05292e3e1f8a51218827168cdclaireho cdf2->ClassRangeCount = 0; /* zero for now. we fill with the number of good entries later */ 10235569331642446be05292e3e1f8a51218827168cdclaireho 10245569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 10255569331642446be05292e3e1f8a51218827168cdclaireho 10265569331642446be05292e3e1f8a51218827168cdclaireho cdf2->ClassRangeRecord = NULL; 10275569331642446be05292e3e1f8a51218827168cdclaireho 10285569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( cdf2->ClassRangeRecord, count, HB_ClassRangeRecord ) ) 10295569331642446be05292e3e1f8a51218827168cdclaireho return error; 10305569331642446be05292e3e1f8a51218827168cdclaireho 10315569331642446be05292e3e1f8a51218827168cdclaireho crr = cdf2->ClassRangeRecord; 10325569331642446be05292e3e1f8a51218827168cdclaireho 10335569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 6L ) ) 10345569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 10355569331642446be05292e3e1f8a51218827168cdclaireho 10365569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 10375569331642446be05292e3e1f8a51218827168cdclaireho { 10385569331642446be05292e3e1f8a51218827168cdclaireho crr[n].Start = GET_UShort(); 10395569331642446be05292e3e1f8a51218827168cdclaireho crr[n].End = GET_UShort(); 10405569331642446be05292e3e1f8a51218827168cdclaireho crr[n].Class = GET_UShort(); 10415569331642446be05292e3e1f8a51218827168cdclaireho 10425569331642446be05292e3e1f8a51218827168cdclaireho /* sanity check */ 10435569331642446be05292e3e1f8a51218827168cdclaireho 10445569331642446be05292e3e1f8a51218827168cdclaireho if ( crr[n].Start > crr[n].End || 10455569331642446be05292e3e1f8a51218827168cdclaireho crr[n].Class >= limit ) 10465569331642446be05292e3e1f8a51218827168cdclaireho { 10475569331642446be05292e3e1f8a51218827168cdclaireho /* XXX 10485569331642446be05292e3e1f8a51218827168cdclaireho * Corrupt entry. Skip it. 10495569331642446be05292e3e1f8a51218827168cdclaireho * This is hit by Nafees Nastaliq font for example 10505569331642446be05292e3e1f8a51218827168cdclaireho */ 10515569331642446be05292e3e1f8a51218827168cdclaireho n--; 10525569331642446be05292e3e1f8a51218827168cdclaireho count--; 10535569331642446be05292e3e1f8a51218827168cdclaireho } 10545569331642446be05292e3e1f8a51218827168cdclaireho } 10555569331642446be05292e3e1f8a51218827168cdclaireho 10565569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 10575569331642446be05292e3e1f8a51218827168cdclaireho 10585569331642446be05292e3e1f8a51218827168cdclaireho cdf2->ClassRangeCount = count; 10595569331642446be05292e3e1f8a51218827168cdclaireho 10605569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 10615569331642446be05292e3e1f8a51218827168cdclaireho 10625569331642446be05292e3e1f8a51218827168cdclairehoFail: 10635569331642446be05292e3e1f8a51218827168cdclaireho FREE( crr ); 10645569331642446be05292e3e1f8a51218827168cdclaireho 10655569331642446be05292e3e1f8a51218827168cdclaireho return error; 10665569331642446be05292e3e1f8a51218827168cdclaireho} 10675569331642446be05292e3e1f8a51218827168cdclaireho 10685569331642446be05292e3e1f8a51218827168cdclaireho 10695569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_ClassDef2( HB_ClassDefFormat2* cdf2 ) 10705569331642446be05292e3e1f8a51218827168cdclaireho{ 10715569331642446be05292e3e1f8a51218827168cdclaireho FREE( cdf2->ClassRangeRecord ); 10725569331642446be05292e3e1f8a51218827168cdclaireho} 10735569331642446be05292e3e1f8a51218827168cdclaireho 10745569331642446be05292e3e1f8a51218827168cdclaireho 10755569331642446be05292e3e1f8a51218827168cdclaireho/* ClassDefinition */ 10765569331642446be05292e3e1f8a51218827168cdclaireho 10775569331642446be05292e3e1f8a51218827168cdclairehoHB_INTERNAL HB_Error 10785569331642446be05292e3e1f8a51218827168cdclaireho_HB_OPEN_Load_ClassDefinition( HB_ClassDefinition* cd, 10795569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort limit, 10805569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 10815569331642446be05292e3e1f8a51218827168cdclaireho{ 10825569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 10835569331642446be05292e3e1f8a51218827168cdclaireho 10845569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 10855569331642446be05292e3e1f8a51218827168cdclaireho return error; 10865569331642446be05292e3e1f8a51218827168cdclaireho 10875569331642446be05292e3e1f8a51218827168cdclaireho cd->ClassFormat = GET_UShort(); 10885569331642446be05292e3e1f8a51218827168cdclaireho 10895569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 10905569331642446be05292e3e1f8a51218827168cdclaireho 10915569331642446be05292e3e1f8a51218827168cdclaireho switch ( cd->ClassFormat ) 10925569331642446be05292e3e1f8a51218827168cdclaireho { 10935569331642446be05292e3e1f8a51218827168cdclaireho case 1: error = Load_ClassDef1( cd, limit, stream ); break; 10945569331642446be05292e3e1f8a51218827168cdclaireho case 2: error = Load_ClassDef2( cd, limit, stream ); break; 10955569331642446be05292e3e1f8a51218827168cdclaireho default: error = ERR(HB_Err_Invalid_SubTable_Format); break; 10965569331642446be05292e3e1f8a51218827168cdclaireho } 10975569331642446be05292e3e1f8a51218827168cdclaireho 10985569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 10995569331642446be05292e3e1f8a51218827168cdclaireho return error; 11005569331642446be05292e3e1f8a51218827168cdclaireho 11015569331642446be05292e3e1f8a51218827168cdclaireho cd->loaded = TRUE; 11025569331642446be05292e3e1f8a51218827168cdclaireho 11035569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 11045569331642446be05292e3e1f8a51218827168cdclaireho} 11055569331642446be05292e3e1f8a51218827168cdclaireho 11065569331642446be05292e3e1f8a51218827168cdclaireho 11075569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error 11085569331642446be05292e3e1f8a51218827168cdclaireho_HB_OPEN_Load_EmptyClassDefinition( HB_ClassDefinition* cd ) 11095569331642446be05292e3e1f8a51218827168cdclaireho{ 11105569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 11115569331642446be05292e3e1f8a51218827168cdclaireho 11125569331642446be05292e3e1f8a51218827168cdclaireho cd->ClassFormat = 1; /* Meaningless */ 11135569331642446be05292e3e1f8a51218827168cdclaireho 11145569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( cd->cd.cd1.ClassValueArray, 1, HB_UShort ) ) 11155569331642446be05292e3e1f8a51218827168cdclaireho return error; 11165569331642446be05292e3e1f8a51218827168cdclaireho 11175569331642446be05292e3e1f8a51218827168cdclaireho cd->loaded = TRUE; 11185569331642446be05292e3e1f8a51218827168cdclaireho 11195569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 11205569331642446be05292e3e1f8a51218827168cdclaireho} 11215569331642446be05292e3e1f8a51218827168cdclaireho 11225569331642446be05292e3e1f8a51218827168cdclairehoHB_INTERNAL HB_Error 11235569331642446be05292e3e1f8a51218827168cdclaireho_HB_OPEN_Load_EmptyOrClassDefinition( HB_ClassDefinition* cd, 11245569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort limit, 11255569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt class_offset, 11265569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt base_offset, 11275569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 11285569331642446be05292e3e1f8a51218827168cdclaireho{ 11295569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 11305569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset; 11315569331642446be05292e3e1f8a51218827168cdclaireho 11325569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 11335569331642446be05292e3e1f8a51218827168cdclaireho 11345569331642446be05292e3e1f8a51218827168cdclaireho if ( class_offset ) 11355569331642446be05292e3e1f8a51218827168cdclaireho { 11365569331642446be05292e3e1f8a51218827168cdclaireho if ( !FILE_Seek( class_offset + base_offset ) ) 11375569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Load_ClassDefinition( cd, limit, stream ); 11385569331642446be05292e3e1f8a51218827168cdclaireho } 11395569331642446be05292e3e1f8a51218827168cdclaireho else 11405569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Load_EmptyClassDefinition ( cd ); 11415569331642446be05292e3e1f8a51218827168cdclaireho 11425569331642446be05292e3e1f8a51218827168cdclaireho if (error == HB_Err_Ok) 11435569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); /* Changes error as a side-effect */ 11445569331642446be05292e3e1f8a51218827168cdclaireho 11455569331642446be05292e3e1f8a51218827168cdclaireho return error; 11465569331642446be05292e3e1f8a51218827168cdclaireho} 11475569331642446be05292e3e1f8a51218827168cdclaireho 11485569331642446be05292e3e1f8a51218827168cdclairehoHB_INTERNAL void 11495569331642446be05292e3e1f8a51218827168cdclaireho_HB_OPEN_Free_ClassDefinition( HB_ClassDefinition* cd ) 11505569331642446be05292e3e1f8a51218827168cdclaireho{ 11515569331642446be05292e3e1f8a51218827168cdclaireho if ( !cd->loaded ) 11525569331642446be05292e3e1f8a51218827168cdclaireho return; 11535569331642446be05292e3e1f8a51218827168cdclaireho 11545569331642446be05292e3e1f8a51218827168cdclaireho switch ( cd->ClassFormat ) 11555569331642446be05292e3e1f8a51218827168cdclaireho { 11565569331642446be05292e3e1f8a51218827168cdclaireho case 1: Free_ClassDef1( &cd->cd.cd1 ); break; 11575569331642446be05292e3e1f8a51218827168cdclaireho case 2: Free_ClassDef2( &cd->cd.cd2 ); break; 11585569331642446be05292e3e1f8a51218827168cdclaireho default: break; 11595569331642446be05292e3e1f8a51218827168cdclaireho } 11605569331642446be05292e3e1f8a51218827168cdclaireho} 11615569331642446be05292e3e1f8a51218827168cdclaireho 11625569331642446be05292e3e1f8a51218827168cdclaireho 11635569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Get_Class1( HB_ClassDefFormat1* cdf1, 11645569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort glyphID, 11655569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* klass, 11665569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* index ) 11675569331642446be05292e3e1f8a51218827168cdclaireho{ 11685569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* cva = cdf1->ClassValueArray; 11695569331642446be05292e3e1f8a51218827168cdclaireho 11705569331642446be05292e3e1f8a51218827168cdclaireho 11715569331642446be05292e3e1f8a51218827168cdclaireho if ( index ) 11725569331642446be05292e3e1f8a51218827168cdclaireho *index = 0; 11735569331642446be05292e3e1f8a51218827168cdclaireho 11745569331642446be05292e3e1f8a51218827168cdclaireho if ( glyphID >= cdf1->StartGlyph && 11755569331642446be05292e3e1f8a51218827168cdclaireho glyphID < cdf1->StartGlyph + cdf1->GlyphCount ) 11765569331642446be05292e3e1f8a51218827168cdclaireho { 11775569331642446be05292e3e1f8a51218827168cdclaireho *klass = cva[glyphID - cdf1->StartGlyph]; 11785569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 11795569331642446be05292e3e1f8a51218827168cdclaireho } 11805569331642446be05292e3e1f8a51218827168cdclaireho else 11815569331642446be05292e3e1f8a51218827168cdclaireho { 11825569331642446be05292e3e1f8a51218827168cdclaireho *klass = 0; 11835569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 11845569331642446be05292e3e1f8a51218827168cdclaireho } 11855569331642446be05292e3e1f8a51218827168cdclaireho} 11865569331642446be05292e3e1f8a51218827168cdclaireho 11875569331642446be05292e3e1f8a51218827168cdclaireho 11885569331642446be05292e3e1f8a51218827168cdclaireho/* we need the index value of the last searched class range record 11895569331642446be05292e3e1f8a51218827168cdclaireho in case of failure for constructed GDEF tables */ 11905569331642446be05292e3e1f8a51218827168cdclaireho 11915569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Get_Class2( HB_ClassDefFormat2* cdf2, 11925569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort glyphID, 11935569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* klass, 11945569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* index ) 11955569331642446be05292e3e1f8a51218827168cdclaireho{ 11965569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error = HB_Err_Ok; 11975569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort min, max, new_min, new_max, middle; 11985569331642446be05292e3e1f8a51218827168cdclaireho 11995569331642446be05292e3e1f8a51218827168cdclaireho HB_ClassRangeRecord* crr = cdf2->ClassRangeRecord; 12005569331642446be05292e3e1f8a51218827168cdclaireho 12015569331642446be05292e3e1f8a51218827168cdclaireho 12025569331642446be05292e3e1f8a51218827168cdclaireho /* binary search */ 12035569331642446be05292e3e1f8a51218827168cdclaireho 12045569331642446be05292e3e1f8a51218827168cdclaireho if ( cdf2->ClassRangeCount == 0 ) 12055569331642446be05292e3e1f8a51218827168cdclaireho { 12065569331642446be05292e3e1f8a51218827168cdclaireho *klass = 0; 12075569331642446be05292e3e1f8a51218827168cdclaireho if ( index ) 12085569331642446be05292e3e1f8a51218827168cdclaireho *index = 0; 12095569331642446be05292e3e1f8a51218827168cdclaireho 12105569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 12115569331642446be05292e3e1f8a51218827168cdclaireho } 12125569331642446be05292e3e1f8a51218827168cdclaireho 12135569331642446be05292e3e1f8a51218827168cdclaireho new_min = 0; 12145569331642446be05292e3e1f8a51218827168cdclaireho new_max = cdf2->ClassRangeCount - 1; 12155569331642446be05292e3e1f8a51218827168cdclaireho 12165569331642446be05292e3e1f8a51218827168cdclaireho do 12175569331642446be05292e3e1f8a51218827168cdclaireho { 12185569331642446be05292e3e1f8a51218827168cdclaireho min = new_min; 12195569331642446be05292e3e1f8a51218827168cdclaireho max = new_max; 12205569331642446be05292e3e1f8a51218827168cdclaireho 12215569331642446be05292e3e1f8a51218827168cdclaireho /* we use (min + max) / 2 = max - (max - min) / 2 to avoid 12225569331642446be05292e3e1f8a51218827168cdclaireho overflow and rounding errors */ 12235569331642446be05292e3e1f8a51218827168cdclaireho 12245569331642446be05292e3e1f8a51218827168cdclaireho middle = max - ( ( max - min ) >> 1 ); 12255569331642446be05292e3e1f8a51218827168cdclaireho 12265569331642446be05292e3e1f8a51218827168cdclaireho if ( glyphID >= crr[middle].Start && glyphID <= crr[middle].End ) 12275569331642446be05292e3e1f8a51218827168cdclaireho { 12285569331642446be05292e3e1f8a51218827168cdclaireho *klass = crr[middle].Class; 12295569331642446be05292e3e1f8a51218827168cdclaireho error = HB_Err_Ok; 12305569331642446be05292e3e1f8a51218827168cdclaireho break; 12315569331642446be05292e3e1f8a51218827168cdclaireho } 12325569331642446be05292e3e1f8a51218827168cdclaireho else if ( glyphID < crr[middle].Start ) 12335569331642446be05292e3e1f8a51218827168cdclaireho { 12345569331642446be05292e3e1f8a51218827168cdclaireho if ( middle == min ) 12355569331642446be05292e3e1f8a51218827168cdclaireho { 12365569331642446be05292e3e1f8a51218827168cdclaireho *klass = 0; 12375569331642446be05292e3e1f8a51218827168cdclaireho error = HB_Err_Not_Covered; 12385569331642446be05292e3e1f8a51218827168cdclaireho break; 12395569331642446be05292e3e1f8a51218827168cdclaireho } 12405569331642446be05292e3e1f8a51218827168cdclaireho new_max = middle - 1; 12415569331642446be05292e3e1f8a51218827168cdclaireho } 12425569331642446be05292e3e1f8a51218827168cdclaireho else 12435569331642446be05292e3e1f8a51218827168cdclaireho { 12445569331642446be05292e3e1f8a51218827168cdclaireho if ( middle == max ) 12455569331642446be05292e3e1f8a51218827168cdclaireho { 12465569331642446be05292e3e1f8a51218827168cdclaireho *klass = 0; 12475569331642446be05292e3e1f8a51218827168cdclaireho error = HB_Err_Not_Covered; 12485569331642446be05292e3e1f8a51218827168cdclaireho break; 12495569331642446be05292e3e1f8a51218827168cdclaireho } 12505569331642446be05292e3e1f8a51218827168cdclaireho new_min = middle + 1; 12515569331642446be05292e3e1f8a51218827168cdclaireho } 12525569331642446be05292e3e1f8a51218827168cdclaireho } while ( min < max ); 12535569331642446be05292e3e1f8a51218827168cdclaireho 12545569331642446be05292e3e1f8a51218827168cdclaireho if ( index ) 12555569331642446be05292e3e1f8a51218827168cdclaireho *index = middle; 12565569331642446be05292e3e1f8a51218827168cdclaireho 12575569331642446be05292e3e1f8a51218827168cdclaireho return error; 12585569331642446be05292e3e1f8a51218827168cdclaireho} 12595569331642446be05292e3e1f8a51218827168cdclaireho 12605569331642446be05292e3e1f8a51218827168cdclaireho 12615569331642446be05292e3e1f8a51218827168cdclairehoHB_INTERNAL HB_Error 12625569331642446be05292e3e1f8a51218827168cdclaireho_HB_OPEN_Get_Class( HB_ClassDefinition* cd, 12635569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort glyphID, 12645569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* klass, 12655569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* index ) 12665569331642446be05292e3e1f8a51218827168cdclaireho{ 12675569331642446be05292e3e1f8a51218827168cdclaireho switch ( cd->ClassFormat ) 12685569331642446be05292e3e1f8a51218827168cdclaireho { 12695569331642446be05292e3e1f8a51218827168cdclaireho case 1: return Get_Class1( &cd->cd.cd1, glyphID, klass, index ); 12705569331642446be05292e3e1f8a51218827168cdclaireho case 2: return Get_Class2( &cd->cd.cd2, glyphID, klass, index ); 12715569331642446be05292e3e1f8a51218827168cdclaireho default: return ERR(HB_Err_Invalid_SubTable_Format); 12725569331642446be05292e3e1f8a51218827168cdclaireho } 12735569331642446be05292e3e1f8a51218827168cdclaireho 12745569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; /* never reached */ 12755569331642446be05292e3e1f8a51218827168cdclaireho} 12765569331642446be05292e3e1f8a51218827168cdclaireho 12775569331642446be05292e3e1f8a51218827168cdclaireho 12785569331642446be05292e3e1f8a51218827168cdclaireho 12795569331642446be05292e3e1f8a51218827168cdclaireho/*************************** 12805569331642446be05292e3e1f8a51218827168cdclaireho * Device related functions 12815569331642446be05292e3e1f8a51218827168cdclaireho ***************************/ 12825569331642446be05292e3e1f8a51218827168cdclaireho 12835569331642446be05292e3e1f8a51218827168cdclaireho 12845569331642446be05292e3e1f8a51218827168cdclairehoHB_INTERNAL HB_Error 128557e6107a9d66a9a97b146def0ef38c010f954be6claireho_HB_OPEN_Load_Device( HB_Device** device, 12865569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 12875569331642446be05292e3e1f8a51218827168cdclaireho{ 128857e6107a9d66a9a97b146def0ef38c010f954be6claireho HB_Device* d; 12895569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 12905569331642446be05292e3e1f8a51218827168cdclaireho 12915569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 12925569331642446be05292e3e1f8a51218827168cdclaireho 12935569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* dv; 12945569331642446be05292e3e1f8a51218827168cdclaireho 12955569331642446be05292e3e1f8a51218827168cdclaireho 12965569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 6L ) ) 12975569331642446be05292e3e1f8a51218827168cdclaireho return error; 12985569331642446be05292e3e1f8a51218827168cdclaireho 129957e6107a9d66a9a97b146def0ef38c010f954be6claireho if ( ALLOC( *device, sizeof(HB_Device)) ) 130057e6107a9d66a9a97b146def0ef38c010f954be6claireho { 130157e6107a9d66a9a97b146def0ef38c010f954be6claireho *device = 0; 130257e6107a9d66a9a97b146def0ef38c010f954be6claireho return error; 130357e6107a9d66a9a97b146def0ef38c010f954be6claireho } 130457e6107a9d66a9a97b146def0ef38c010f954be6claireho 130557e6107a9d66a9a97b146def0ef38c010f954be6claireho d = *device; 130657e6107a9d66a9a97b146def0ef38c010f954be6claireho 13075569331642446be05292e3e1f8a51218827168cdclaireho d->StartSize = GET_UShort(); 13085569331642446be05292e3e1f8a51218827168cdclaireho d->EndSize = GET_UShort(); 13095569331642446be05292e3e1f8a51218827168cdclaireho d->DeltaFormat = GET_UShort(); 13105569331642446be05292e3e1f8a51218827168cdclaireho 13115569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 13125569331642446be05292e3e1f8a51218827168cdclaireho 13135569331642446be05292e3e1f8a51218827168cdclaireho d->DeltaValue = NULL; 13145569331642446be05292e3e1f8a51218827168cdclaireho 13155569331642446be05292e3e1f8a51218827168cdclaireho if ( d->StartSize > d->EndSize || 13165569331642446be05292e3e1f8a51218827168cdclaireho d->DeltaFormat == 0 || d->DeltaFormat > 3 ) 13175569331642446be05292e3e1f8a51218827168cdclaireho { 13185569331642446be05292e3e1f8a51218827168cdclaireho /* XXX 13195569331642446be05292e3e1f8a51218827168cdclaireho * I've seen fontforge generate DeltaFormat == 0. 13205569331642446be05292e3e1f8a51218827168cdclaireho * Just return Ok and let the NULL DeltaValue disable 13215569331642446be05292e3e1f8a51218827168cdclaireho * this table. 13225569331642446be05292e3e1f8a51218827168cdclaireho */ 13235569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 13245569331642446be05292e3e1f8a51218827168cdclaireho } 13255569331642446be05292e3e1f8a51218827168cdclaireho 13265569331642446be05292e3e1f8a51218827168cdclaireho count = ( ( d->EndSize - d->StartSize + 1 ) >> 13275569331642446be05292e3e1f8a51218827168cdclaireho ( 4 - d->DeltaFormat ) ) + 1; 13285569331642446be05292e3e1f8a51218827168cdclaireho 13295569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( d->DeltaValue, count, HB_UShort ) ) 133057e6107a9d66a9a97b146def0ef38c010f954be6claireho { 133157e6107a9d66a9a97b146def0ef38c010f954be6claireho FREE( *device ); 133257e6107a9d66a9a97b146def0ef38c010f954be6claireho *device = 0; 13335569331642446be05292e3e1f8a51218827168cdclaireho return error; 133457e6107a9d66a9a97b146def0ef38c010f954be6claireho } 13355569331642446be05292e3e1f8a51218827168cdclaireho 13365569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 2L ) ) 13375569331642446be05292e3e1f8a51218827168cdclaireho { 13385569331642446be05292e3e1f8a51218827168cdclaireho FREE( d->DeltaValue ); 133957e6107a9d66a9a97b146def0ef38c010f954be6claireho FREE( *device ); 134057e6107a9d66a9a97b146def0ef38c010f954be6claireho *device = 0; 13415569331642446be05292e3e1f8a51218827168cdclaireho return error; 13425569331642446be05292e3e1f8a51218827168cdclaireho } 13435569331642446be05292e3e1f8a51218827168cdclaireho 13445569331642446be05292e3e1f8a51218827168cdclaireho dv = d->DeltaValue; 13455569331642446be05292e3e1f8a51218827168cdclaireho 13465569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 13475569331642446be05292e3e1f8a51218827168cdclaireho dv[n] = GET_UShort(); 13485569331642446be05292e3e1f8a51218827168cdclaireho 13495569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 13505569331642446be05292e3e1f8a51218827168cdclaireho 13515569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 13525569331642446be05292e3e1f8a51218827168cdclaireho} 13535569331642446be05292e3e1f8a51218827168cdclaireho 13545569331642446be05292e3e1f8a51218827168cdclaireho 13555569331642446be05292e3e1f8a51218827168cdclairehoHB_INTERNAL void 13565569331642446be05292e3e1f8a51218827168cdclaireho_HB_OPEN_Free_Device( HB_Device* d ) 13575569331642446be05292e3e1f8a51218827168cdclaireho{ 135857e6107a9d66a9a97b146def0ef38c010f954be6claireho if ( d ) 135957e6107a9d66a9a97b146def0ef38c010f954be6claireho { 136057e6107a9d66a9a97b146def0ef38c010f954be6claireho FREE( d->DeltaValue ); 136157e6107a9d66a9a97b146def0ef38c010f954be6claireho FREE( d ); 136257e6107a9d66a9a97b146def0ef38c010f954be6claireho } 13635569331642446be05292e3e1f8a51218827168cdclaireho} 13645569331642446be05292e3e1f8a51218827168cdclaireho 13655569331642446be05292e3e1f8a51218827168cdclaireho 13665569331642446be05292e3e1f8a51218827168cdclaireho/* Since we have the delta values stored in compressed form, we must 13675569331642446be05292e3e1f8a51218827168cdclaireho uncompress it now. To simplify the interface, the function always 13685569331642446be05292e3e1f8a51218827168cdclaireho returns a meaningful value in `value'; the error is just for 13695569331642446be05292e3e1f8a51218827168cdclaireho information. 13705569331642446be05292e3e1f8a51218827168cdclaireho | | 13715569331642446be05292e3e1f8a51218827168cdclaireho format = 1: 0011223344556677|8899101112131415|... 13725569331642446be05292e3e1f8a51218827168cdclaireho | | 13735569331642446be05292e3e1f8a51218827168cdclaireho byte 1 byte 2 13745569331642446be05292e3e1f8a51218827168cdclaireho 13755569331642446be05292e3e1f8a51218827168cdclaireho 00: (byte >> 14) & mask 13765569331642446be05292e3e1f8a51218827168cdclaireho 11: (byte >> 12) & mask 13775569331642446be05292e3e1f8a51218827168cdclaireho ... 13785569331642446be05292e3e1f8a51218827168cdclaireho 13795569331642446be05292e3e1f8a51218827168cdclaireho mask = 0x0003 13805569331642446be05292e3e1f8a51218827168cdclaireho | | 13815569331642446be05292e3e1f8a51218827168cdclaireho format = 2: 0000111122223333|4444555566667777|... 13825569331642446be05292e3e1f8a51218827168cdclaireho | | 13835569331642446be05292e3e1f8a51218827168cdclaireho byte 1 byte 2 13845569331642446be05292e3e1f8a51218827168cdclaireho 13855569331642446be05292e3e1f8a51218827168cdclaireho 0000: (byte >> 12) & mask 13865569331642446be05292e3e1f8a51218827168cdclaireho 1111: (byte >> 8) & mask 13875569331642446be05292e3e1f8a51218827168cdclaireho ... 13885569331642446be05292e3e1f8a51218827168cdclaireho 13895569331642446be05292e3e1f8a51218827168cdclaireho mask = 0x000F 13905569331642446be05292e3e1f8a51218827168cdclaireho | | 13915569331642446be05292e3e1f8a51218827168cdclaireho format = 3: 0000000011111111|2222222233333333|... 13925569331642446be05292e3e1f8a51218827168cdclaireho | | 13935569331642446be05292e3e1f8a51218827168cdclaireho byte 1 byte 2 13945569331642446be05292e3e1f8a51218827168cdclaireho 13955569331642446be05292e3e1f8a51218827168cdclaireho 00000000: (byte >> 8) & mask 13965569331642446be05292e3e1f8a51218827168cdclaireho 11111111: (byte >> 0) & mask 13975569331642446be05292e3e1f8a51218827168cdclaireho .... 13985569331642446be05292e3e1f8a51218827168cdclaireho 13995569331642446be05292e3e1f8a51218827168cdclaireho mask = 0x00FF */ 14005569331642446be05292e3e1f8a51218827168cdclaireho 14015569331642446be05292e3e1f8a51218827168cdclairehoHB_INTERNAL HB_Error 14025569331642446be05292e3e1f8a51218827168cdclaireho_HB_OPEN_Get_Device( HB_Device* d, 14035569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort size, 14045569331642446be05292e3e1f8a51218827168cdclaireho HB_Short* value ) 14055569331642446be05292e3e1f8a51218827168cdclaireho{ 140657e6107a9d66a9a97b146def0ef38c010f954be6claireho HB_UShort byte, bits, mask, s; 14075569331642446be05292e3e1f8a51218827168cdclaireho 140857e6107a9d66a9a97b146def0ef38c010f954be6claireho if ( d && d->DeltaValue && size >= d->StartSize && size <= d->EndSize ) 14095569331642446be05292e3e1f8a51218827168cdclaireho { 141057e6107a9d66a9a97b146def0ef38c010f954be6claireho HB_UShort f = d->DeltaFormat; 14115569331642446be05292e3e1f8a51218827168cdclaireho s = size - d->StartSize; 14125569331642446be05292e3e1f8a51218827168cdclaireho byte = d->DeltaValue[s >> ( 4 - f )]; 14135569331642446be05292e3e1f8a51218827168cdclaireho bits = byte >> ( 16 - ( ( s % ( 1 << ( 4 - f ) ) + 1 ) << f ) ); 14145569331642446be05292e3e1f8a51218827168cdclaireho mask = 0xFFFF >> ( 16 - ( 1 << f ) ); 14155569331642446be05292e3e1f8a51218827168cdclaireho 14165569331642446be05292e3e1f8a51218827168cdclaireho *value = (HB_Short)( bits & mask ); 14175569331642446be05292e3e1f8a51218827168cdclaireho 14185569331642446be05292e3e1f8a51218827168cdclaireho /* conversion to a signed value */ 14195569331642446be05292e3e1f8a51218827168cdclaireho 14205569331642446be05292e3e1f8a51218827168cdclaireho if ( *value >= ( ( mask + 1 ) >> 1 ) ) 14215569331642446be05292e3e1f8a51218827168cdclaireho *value -= mask + 1; 14225569331642446be05292e3e1f8a51218827168cdclaireho 14235569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 14245569331642446be05292e3e1f8a51218827168cdclaireho } 14255569331642446be05292e3e1f8a51218827168cdclaireho else 14265569331642446be05292e3e1f8a51218827168cdclaireho { 14275569331642446be05292e3e1f8a51218827168cdclaireho *value = 0; 14285569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 14295569331642446be05292e3e1f8a51218827168cdclaireho } 14305569331642446be05292e3e1f8a51218827168cdclaireho} 14315569331642446be05292e3e1f8a51218827168cdclaireho 14325569331642446be05292e3e1f8a51218827168cdclaireho 14335569331642446be05292e3e1f8a51218827168cdclaireho/* END */ 1434