15569331642446be05292e3e1f8a51218827168cdclaireho/* 25569331642446be05292e3e1f8a51218827168cdclaireho * Copyright (C) 1998-2004 David Turner and Werner Lemberg 35569331642446be05292e3e1f8a51218827168cdclaireho * Copyright (C) 2006 Behdad Esfahbod 45569331642446be05292e3e1f8a51218827168cdclaireho * Copyright (C) 2007 Red Hat, Inc. 55569331642446be05292e3e1f8a51218827168cdclaireho * 65569331642446be05292e3e1f8a51218827168cdclaireho * This is part of HarfBuzz, an OpenType Layout engine library. 75569331642446be05292e3e1f8a51218827168cdclaireho * 85569331642446be05292e3e1f8a51218827168cdclaireho * Permission is hereby granted, without written agreement and without 95569331642446be05292e3e1f8a51218827168cdclaireho * license or royalty fees, to use, copy, modify, and distribute this 105569331642446be05292e3e1f8a51218827168cdclaireho * software and its documentation for any purpose, provided that the 115569331642446be05292e3e1f8a51218827168cdclaireho * above copyright notice and the following two paragraphs appear in 125569331642446be05292e3e1f8a51218827168cdclaireho * all copies of this software. 135569331642446be05292e3e1f8a51218827168cdclaireho * 145569331642446be05292e3e1f8a51218827168cdclaireho * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 155569331642446be05292e3e1f8a51218827168cdclaireho * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 165569331642446be05292e3e1f8a51218827168cdclaireho * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 175569331642446be05292e3e1f8a51218827168cdclaireho * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 185569331642446be05292e3e1f8a51218827168cdclaireho * DAMAGE. 195569331642446be05292e3e1f8a51218827168cdclaireho * 205569331642446be05292e3e1f8a51218827168cdclaireho * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 215569331642446be05292e3e1f8a51218827168cdclaireho * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 225569331642446be05292e3e1f8a51218827168cdclaireho * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 235569331642446be05292e3e1f8a51218827168cdclaireho * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 245569331642446be05292e3e1f8a51218827168cdclaireho * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 255569331642446be05292e3e1f8a51218827168cdclaireho * 265569331642446be05292e3e1f8a51218827168cdclaireho * Red Hat Author(s): Behdad Esfahbod 275569331642446be05292e3e1f8a51218827168cdclaireho */ 285569331642446be05292e3e1f8a51218827168cdclaireho 295569331642446be05292e3e1f8a51218827168cdclaireho#include "harfbuzz-impl.h" 305569331642446be05292e3e1f8a51218827168cdclaireho#include "harfbuzz-gsub-private.h" 315569331642446be05292e3e1f8a51218827168cdclaireho#include "harfbuzz-open-private.h" 325569331642446be05292e3e1f8a51218827168cdclaireho#include "harfbuzz-gdef-private.h" 335569331642446be05292e3e1f8a51218827168cdclaireho 345569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error GSUB_Do_Glyph_Lookup( HB_GSUBHeader* gsub, 355569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort lookup_index, 365569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 375569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 385569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ); 395569331642446be05292e3e1f8a51218827168cdclaireho 405569331642446be05292e3e1f8a51218827168cdclaireho 415569331642446be05292e3e1f8a51218827168cdclaireho 425569331642446be05292e3e1f8a51218827168cdclaireho/********************** 435569331642446be05292e3e1f8a51218827168cdclaireho * Auxiliary functions 445569331642446be05292e3e1f8a51218827168cdclaireho **********************/ 455569331642446be05292e3e1f8a51218827168cdclaireho 465569331642446be05292e3e1f8a51218827168cdclaireho 475569331642446be05292e3e1f8a51218827168cdclaireho 485569331642446be05292e3e1f8a51218827168cdclairehoHB_Error HB_Load_GSUB_Table( HB_Stream stream, 495569331642446be05292e3e1f8a51218827168cdclaireho HB_GSUBHeader** retptr, 505569331642446be05292e3e1f8a51218827168cdclaireho HB_GDEFHeader* gdef, 515569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream gdefStream ) 525569331642446be05292e3e1f8a51218827168cdclaireho{ 535569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 545569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 555569331642446be05292e3e1f8a51218827168cdclaireho 565569331642446be05292e3e1f8a51218827168cdclaireho HB_GSUBHeader* gsub; 575569331642446be05292e3e1f8a51218827168cdclaireho 585569331642446be05292e3e1f8a51218827168cdclaireho if ( !retptr ) 595569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 605569331642446be05292e3e1f8a51218827168cdclaireho 615569331642446be05292e3e1f8a51218827168cdclaireho if ( GOTO_Table( TTAG_GSUB ) ) 625569331642446be05292e3e1f8a51218827168cdclaireho return error; 635569331642446be05292e3e1f8a51218827168cdclaireho 645569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 655569331642446be05292e3e1f8a51218827168cdclaireho 665569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC ( gsub, sizeof( *gsub ) ) ) 675569331642446be05292e3e1f8a51218827168cdclaireho return error; 685569331642446be05292e3e1f8a51218827168cdclaireho 695569331642446be05292e3e1f8a51218827168cdclaireho 705569331642446be05292e3e1f8a51218827168cdclaireho /* skip version */ 715569331642446be05292e3e1f8a51218827168cdclaireho 725569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( base_offset + 4L ) || 735569331642446be05292e3e1f8a51218827168cdclaireho ACCESS_Frame( 2L ) ) 745569331642446be05292e3e1f8a51218827168cdclaireho goto Fail4; 755569331642446be05292e3e1f8a51218827168cdclaireho 765569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 775569331642446be05292e3e1f8a51218827168cdclaireho 785569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 795569331642446be05292e3e1f8a51218827168cdclaireho 805569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 815569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 825569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_ScriptList( &gsub->ScriptList, 835569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 845569331642446be05292e3e1f8a51218827168cdclaireho goto Fail4; 855569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 865569331642446be05292e3e1f8a51218827168cdclaireho 875569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 885569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 895569331642446be05292e3e1f8a51218827168cdclaireho 905569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 915569331642446be05292e3e1f8a51218827168cdclaireho 925569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 935569331642446be05292e3e1f8a51218827168cdclaireho 945569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 955569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 965569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_FeatureList( &gsub->FeatureList, 975569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 985569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 995569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 1005569331642446be05292e3e1f8a51218827168cdclaireho 1015569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 1025569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 1035569331642446be05292e3e1f8a51218827168cdclaireho 1045569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 1055569331642446be05292e3e1f8a51218827168cdclaireho 1065569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 1075569331642446be05292e3e1f8a51218827168cdclaireho 1085569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 1095569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 1105569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_LookupList( &gsub->LookupList, 1115569331642446be05292e3e1f8a51218827168cdclaireho stream, HB_Type_GSUB ) ) != HB_Err_Ok ) 1125569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 1135569331642446be05292e3e1f8a51218827168cdclaireho 1145569331642446be05292e3e1f8a51218827168cdclaireho gsub->gdef = gdef; /* can be NULL */ 1155569331642446be05292e3e1f8a51218827168cdclaireho 1165569331642446be05292e3e1f8a51218827168cdclaireho if ( ( error = _HB_GDEF_LoadMarkAttachClassDef_From_LookupFlags( gdef, gdefStream, 1175569331642446be05292e3e1f8a51218827168cdclaireho gsub->LookupList.Lookup, 1185569331642446be05292e3e1f8a51218827168cdclaireho gsub->LookupList.LookupCount ) ) ) 1195569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 1205569331642446be05292e3e1f8a51218827168cdclaireho 1215569331642446be05292e3e1f8a51218827168cdclaireho *retptr = gsub; 1225569331642446be05292e3e1f8a51218827168cdclaireho 1235569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 1245569331642446be05292e3e1f8a51218827168cdclaireho 1255569331642446be05292e3e1f8a51218827168cdclairehoFail1: 1265569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_LookupList( &gsub->LookupList, HB_Type_GSUB ); 1275569331642446be05292e3e1f8a51218827168cdclaireho 1285569331642446be05292e3e1f8a51218827168cdclairehoFail2: 1295569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_FeatureList( &gsub->FeatureList ); 1305569331642446be05292e3e1f8a51218827168cdclaireho 1315569331642446be05292e3e1f8a51218827168cdclairehoFail3: 1325569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_ScriptList( &gsub->ScriptList ); 1335569331642446be05292e3e1f8a51218827168cdclaireho 1345569331642446be05292e3e1f8a51218827168cdclairehoFail4: 1355569331642446be05292e3e1f8a51218827168cdclaireho FREE ( gsub ); 1365569331642446be05292e3e1f8a51218827168cdclaireho 1375569331642446be05292e3e1f8a51218827168cdclaireho 1385569331642446be05292e3e1f8a51218827168cdclaireho return error; 1395569331642446be05292e3e1f8a51218827168cdclaireho} 1405569331642446be05292e3e1f8a51218827168cdclaireho 1415569331642446be05292e3e1f8a51218827168cdclaireho 1425569331642446be05292e3e1f8a51218827168cdclairehoHB_Error HB_Done_GSUB_Table( HB_GSUBHeader* gsub ) 1435569331642446be05292e3e1f8a51218827168cdclaireho{ 1445569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_LookupList( &gsub->LookupList, HB_Type_GSUB ); 1455569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_FeatureList( &gsub->FeatureList ); 1465569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_ScriptList( &gsub->ScriptList ); 1475569331642446be05292e3e1f8a51218827168cdclaireho 1485569331642446be05292e3e1f8a51218827168cdclaireho FREE( gsub ); 1495569331642446be05292e3e1f8a51218827168cdclaireho 1505569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 1515569331642446be05292e3e1f8a51218827168cdclaireho} 1525569331642446be05292e3e1f8a51218827168cdclaireho 1535569331642446be05292e3e1f8a51218827168cdclaireho/***************************** 1545569331642446be05292e3e1f8a51218827168cdclaireho * SubTable related functions 1555569331642446be05292e3e1f8a51218827168cdclaireho *****************************/ 1565569331642446be05292e3e1f8a51218827168cdclaireho 1575569331642446be05292e3e1f8a51218827168cdclaireho 1585569331642446be05292e3e1f8a51218827168cdclaireho/* LookupType 1 */ 1595569331642446be05292e3e1f8a51218827168cdclaireho 1605569331642446be05292e3e1f8a51218827168cdclaireho/* SingleSubstFormat1 */ 1615569331642446be05292e3e1f8a51218827168cdclaireho/* SingleSubstFormat2 */ 1625569331642446be05292e3e1f8a51218827168cdclaireho 1635569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_SingleSubst( HB_GSUB_SubTable* st, 1645569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 1655569331642446be05292e3e1f8a51218827168cdclaireho{ 1665569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 1675569331642446be05292e3e1f8a51218827168cdclaireho HB_SingleSubst* ss = &st->single; 1685569331642446be05292e3e1f8a51218827168cdclaireho 1695569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 1705569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 1715569331642446be05292e3e1f8a51218827168cdclaireho 1725569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* s; 1735569331642446be05292e3e1f8a51218827168cdclaireho 1745569331642446be05292e3e1f8a51218827168cdclaireho 1755569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 1765569331642446be05292e3e1f8a51218827168cdclaireho 1775569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 4L ) ) 1785569331642446be05292e3e1f8a51218827168cdclaireho return error; 1795569331642446be05292e3e1f8a51218827168cdclaireho 1805569331642446be05292e3e1f8a51218827168cdclaireho ss->SubstFormat = GET_UShort(); 1815569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 1825569331642446be05292e3e1f8a51218827168cdclaireho 1835569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 1845569331642446be05292e3e1f8a51218827168cdclaireho 1855569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 1865569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 1875569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &ss->Coverage, stream ) ) != HB_Err_Ok ) 1885569331642446be05292e3e1f8a51218827168cdclaireho return error; 1895569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 1905569331642446be05292e3e1f8a51218827168cdclaireho 1915569331642446be05292e3e1f8a51218827168cdclaireho switch ( ss->SubstFormat ) 1925569331642446be05292e3e1f8a51218827168cdclaireho { 1935569331642446be05292e3e1f8a51218827168cdclaireho case 1: 1945569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 1955569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 1965569331642446be05292e3e1f8a51218827168cdclaireho 1975569331642446be05292e3e1f8a51218827168cdclaireho ss->ssf.ssf1.DeltaGlyphID = GET_UShort(); 1985569331642446be05292e3e1f8a51218827168cdclaireho 1995569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 2005569331642446be05292e3e1f8a51218827168cdclaireho 2015569331642446be05292e3e1f8a51218827168cdclaireho break; 2025569331642446be05292e3e1f8a51218827168cdclaireho 2035569331642446be05292e3e1f8a51218827168cdclaireho case 2: 2045569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 2055569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 2065569331642446be05292e3e1f8a51218827168cdclaireho 2075569331642446be05292e3e1f8a51218827168cdclaireho count = ss->ssf.ssf2.GlyphCount = GET_UShort(); 2085569331642446be05292e3e1f8a51218827168cdclaireho 2095569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 2105569331642446be05292e3e1f8a51218827168cdclaireho 2115569331642446be05292e3e1f8a51218827168cdclaireho ss->ssf.ssf2.Substitute = NULL; 2125569331642446be05292e3e1f8a51218827168cdclaireho 2135569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( ss->ssf.ssf2.Substitute, count, HB_UShort ) ) 2145569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 2155569331642446be05292e3e1f8a51218827168cdclaireho 2165569331642446be05292e3e1f8a51218827168cdclaireho s = ss->ssf.ssf2.Substitute; 2175569331642446be05292e3e1f8a51218827168cdclaireho 2185569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 2L ) ) 2195569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 2205569331642446be05292e3e1f8a51218827168cdclaireho 2215569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 2225569331642446be05292e3e1f8a51218827168cdclaireho s[n] = GET_UShort(); 2235569331642446be05292e3e1f8a51218827168cdclaireho 2245569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 2255569331642446be05292e3e1f8a51218827168cdclaireho 2265569331642446be05292e3e1f8a51218827168cdclaireho break; 2275569331642446be05292e3e1f8a51218827168cdclaireho 2285569331642446be05292e3e1f8a51218827168cdclaireho default: 2295569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable_Format); 2305569331642446be05292e3e1f8a51218827168cdclaireho } 2315569331642446be05292e3e1f8a51218827168cdclaireho 2325569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 2335569331642446be05292e3e1f8a51218827168cdclaireho 2345569331642446be05292e3e1f8a51218827168cdclairehoFail1: 2355569331642446be05292e3e1f8a51218827168cdclaireho FREE( s ); 2365569331642446be05292e3e1f8a51218827168cdclaireho 2375569331642446be05292e3e1f8a51218827168cdclairehoFail2: 2385569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &ss->Coverage ); 2395569331642446be05292e3e1f8a51218827168cdclaireho return error; 2405569331642446be05292e3e1f8a51218827168cdclaireho} 2415569331642446be05292e3e1f8a51218827168cdclaireho 2425569331642446be05292e3e1f8a51218827168cdclaireho 2435569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_SingleSubst( HB_GSUB_SubTable* st ) 2445569331642446be05292e3e1f8a51218827168cdclaireho{ 2455569331642446be05292e3e1f8a51218827168cdclaireho HB_SingleSubst* ss = &st->single; 2465569331642446be05292e3e1f8a51218827168cdclaireho 2475569331642446be05292e3e1f8a51218827168cdclaireho switch ( ss->SubstFormat ) 2485569331642446be05292e3e1f8a51218827168cdclaireho { 2495569331642446be05292e3e1f8a51218827168cdclaireho case 1: 2505569331642446be05292e3e1f8a51218827168cdclaireho break; 2515569331642446be05292e3e1f8a51218827168cdclaireho 2525569331642446be05292e3e1f8a51218827168cdclaireho case 2: 2535569331642446be05292e3e1f8a51218827168cdclaireho FREE( ss->ssf.ssf2.Substitute ); 2545569331642446be05292e3e1f8a51218827168cdclaireho break; 2555569331642446be05292e3e1f8a51218827168cdclaireho 2565569331642446be05292e3e1f8a51218827168cdclaireho default: 2575569331642446be05292e3e1f8a51218827168cdclaireho break; 2585569331642446be05292e3e1f8a51218827168cdclaireho } 2595569331642446be05292e3e1f8a51218827168cdclaireho 2605569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &ss->Coverage ); 2615569331642446be05292e3e1f8a51218827168cdclaireho} 2625569331642446be05292e3e1f8a51218827168cdclaireho 2635569331642446be05292e3e1f8a51218827168cdclaireho 2645569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Lookup_SingleSubst( HB_GSUBHeader* gsub, 2655569331642446be05292e3e1f8a51218827168cdclaireho HB_GSUB_SubTable* st, 2665569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 2675569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort flags, 2685569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 2695569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 2705569331642446be05292e3e1f8a51218827168cdclaireho{ 2715569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort index, value, property; 2725569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 2735569331642446be05292e3e1f8a51218827168cdclaireho HB_SingleSubst* ss = &st->single; 2745569331642446be05292e3e1f8a51218827168cdclaireho HB_GDEFHeader* gdef = gsub->gdef; 2755569331642446be05292e3e1f8a51218827168cdclaireho 2765569331642446be05292e3e1f8a51218827168cdclaireho HB_UNUSED(nesting_level); 2775569331642446be05292e3e1f8a51218827168cdclaireho 2785569331642446be05292e3e1f8a51218827168cdclaireho if ( context_length != 0xFFFF && context_length < 1 ) 2795569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 2805569331642446be05292e3e1f8a51218827168cdclaireho 2815569331642446be05292e3e1f8a51218827168cdclaireho if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) 2825569331642446be05292e3e1f8a51218827168cdclaireho return error; 2835569331642446be05292e3e1f8a51218827168cdclaireho 2845569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &ss->Coverage, IN_CURGLYPH(), &index ); 2855569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 2865569331642446be05292e3e1f8a51218827168cdclaireho return error; 2875569331642446be05292e3e1f8a51218827168cdclaireho 2885569331642446be05292e3e1f8a51218827168cdclaireho switch ( ss->SubstFormat ) 2895569331642446be05292e3e1f8a51218827168cdclaireho { 2905569331642446be05292e3e1f8a51218827168cdclaireho case 1: 2915569331642446be05292e3e1f8a51218827168cdclaireho value = ( IN_CURGLYPH() + ss->ssf.ssf1.DeltaGlyphID ) & 0xFFFF; 2925569331642446be05292e3e1f8a51218827168cdclaireho if ( REPLACE_Glyph( buffer, value, nesting_level ) ) 2935569331642446be05292e3e1f8a51218827168cdclaireho return error; 2945569331642446be05292e3e1f8a51218827168cdclaireho break; 2955569331642446be05292e3e1f8a51218827168cdclaireho 2965569331642446be05292e3e1f8a51218827168cdclaireho case 2: 2975569331642446be05292e3e1f8a51218827168cdclaireho if ( index >= ss->ssf.ssf2.GlyphCount ) 2985569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable); 2995569331642446be05292e3e1f8a51218827168cdclaireho value = ss->ssf.ssf2.Substitute[index]; 3005569331642446be05292e3e1f8a51218827168cdclaireho if ( REPLACE_Glyph( buffer, value, nesting_level ) ) 3015569331642446be05292e3e1f8a51218827168cdclaireho return error; 3025569331642446be05292e3e1f8a51218827168cdclaireho break; 3035569331642446be05292e3e1f8a51218827168cdclaireho 3045569331642446be05292e3e1f8a51218827168cdclaireho default: 3055569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable); 3065569331642446be05292e3e1f8a51218827168cdclaireho } 3075569331642446be05292e3e1f8a51218827168cdclaireho 3085569331642446be05292e3e1f8a51218827168cdclaireho if ( gdef && gdef->NewGlyphClasses ) 3095569331642446be05292e3e1f8a51218827168cdclaireho { 3105569331642446be05292e3e1f8a51218827168cdclaireho /* we inherit the old glyph class to the substituted glyph */ 3115569331642446be05292e3e1f8a51218827168cdclaireho 3125569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_GDEF_Add_Glyph_Property( gdef, value, property ); 3135569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 3145569331642446be05292e3e1f8a51218827168cdclaireho return error; 3155569331642446be05292e3e1f8a51218827168cdclaireho } 3165569331642446be05292e3e1f8a51218827168cdclaireho 3175569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 3185569331642446be05292e3e1f8a51218827168cdclaireho} 3195569331642446be05292e3e1f8a51218827168cdclaireho 3205569331642446be05292e3e1f8a51218827168cdclaireho 3215569331642446be05292e3e1f8a51218827168cdclaireho/* LookupType 2 */ 3225569331642446be05292e3e1f8a51218827168cdclaireho 3235569331642446be05292e3e1f8a51218827168cdclaireho/* Sequence */ 3245569331642446be05292e3e1f8a51218827168cdclaireho 3255569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_Sequence( HB_Sequence* s, 3265569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 3275569331642446be05292e3e1f8a51218827168cdclaireho{ 3285569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 3295569331642446be05292e3e1f8a51218827168cdclaireho 3305569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 3315569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* sub; 3325569331642446be05292e3e1f8a51218827168cdclaireho 3335569331642446be05292e3e1f8a51218827168cdclaireho 3345569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 3355569331642446be05292e3e1f8a51218827168cdclaireho return error; 3365569331642446be05292e3e1f8a51218827168cdclaireho 3375569331642446be05292e3e1f8a51218827168cdclaireho count = s->GlyphCount = GET_UShort(); 3385569331642446be05292e3e1f8a51218827168cdclaireho 3395569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 3405569331642446be05292e3e1f8a51218827168cdclaireho 3415569331642446be05292e3e1f8a51218827168cdclaireho s->Substitute = NULL; 3425569331642446be05292e3e1f8a51218827168cdclaireho 3435569331642446be05292e3e1f8a51218827168cdclaireho if ( count ) 3445569331642446be05292e3e1f8a51218827168cdclaireho { 3455569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( s->Substitute, count, HB_UShort ) ) 3465569331642446be05292e3e1f8a51218827168cdclaireho return error; 3475569331642446be05292e3e1f8a51218827168cdclaireho 3485569331642446be05292e3e1f8a51218827168cdclaireho sub = s->Substitute; 3495569331642446be05292e3e1f8a51218827168cdclaireho 3505569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 2L ) ) 3515569331642446be05292e3e1f8a51218827168cdclaireho { 3525569331642446be05292e3e1f8a51218827168cdclaireho FREE( sub ); 3535569331642446be05292e3e1f8a51218827168cdclaireho return error; 3545569331642446be05292e3e1f8a51218827168cdclaireho } 3555569331642446be05292e3e1f8a51218827168cdclaireho 3565569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 3575569331642446be05292e3e1f8a51218827168cdclaireho sub[n] = GET_UShort(); 3585569331642446be05292e3e1f8a51218827168cdclaireho 3595569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 3605569331642446be05292e3e1f8a51218827168cdclaireho } 3615569331642446be05292e3e1f8a51218827168cdclaireho 3625569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 3635569331642446be05292e3e1f8a51218827168cdclaireho} 3645569331642446be05292e3e1f8a51218827168cdclaireho 3655569331642446be05292e3e1f8a51218827168cdclaireho 3665569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_Sequence( HB_Sequence* s ) 3675569331642446be05292e3e1f8a51218827168cdclaireho{ 3685569331642446be05292e3e1f8a51218827168cdclaireho FREE( s->Substitute ); 3695569331642446be05292e3e1f8a51218827168cdclaireho} 3705569331642446be05292e3e1f8a51218827168cdclaireho 3715569331642446be05292e3e1f8a51218827168cdclaireho 3725569331642446be05292e3e1f8a51218827168cdclaireho/* MultipleSubstFormat1 */ 3735569331642446be05292e3e1f8a51218827168cdclaireho 3745569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_MultipleSubst( HB_GSUB_SubTable* st, 3755569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 3765569331642446be05292e3e1f8a51218827168cdclaireho{ 3775569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 3785569331642446be05292e3e1f8a51218827168cdclaireho HB_MultipleSubst* ms = &st->multiple; 3795569331642446be05292e3e1f8a51218827168cdclaireho 3805569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n = 0, m, count; 3815569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 3825569331642446be05292e3e1f8a51218827168cdclaireho 3835569331642446be05292e3e1f8a51218827168cdclaireho HB_Sequence* s; 3845569331642446be05292e3e1f8a51218827168cdclaireho 3855569331642446be05292e3e1f8a51218827168cdclaireho 3865569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 3875569331642446be05292e3e1f8a51218827168cdclaireho 3885569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 4L ) ) 3895569331642446be05292e3e1f8a51218827168cdclaireho return error; 3905569331642446be05292e3e1f8a51218827168cdclaireho 3915569331642446be05292e3e1f8a51218827168cdclaireho ms->SubstFormat = GET_UShort(); /* should be 1 */ 3925569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 3935569331642446be05292e3e1f8a51218827168cdclaireho 3945569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 3955569331642446be05292e3e1f8a51218827168cdclaireho 3965569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 3975569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 3985569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &ms->Coverage, stream ) ) != HB_Err_Ok ) 3995569331642446be05292e3e1f8a51218827168cdclaireho return error; 4005569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 4015569331642446be05292e3e1f8a51218827168cdclaireho 4025569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 4035569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 4045569331642446be05292e3e1f8a51218827168cdclaireho 4055569331642446be05292e3e1f8a51218827168cdclaireho count = ms->SequenceCount = GET_UShort(); 4065569331642446be05292e3e1f8a51218827168cdclaireho 4075569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 4085569331642446be05292e3e1f8a51218827168cdclaireho 4095569331642446be05292e3e1f8a51218827168cdclaireho ms->Sequence = NULL; 4105569331642446be05292e3e1f8a51218827168cdclaireho 4115569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( ms->Sequence, count, HB_Sequence ) ) 4125569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 4135569331642446be05292e3e1f8a51218827168cdclaireho 4145569331642446be05292e3e1f8a51218827168cdclaireho s = ms->Sequence; 4155569331642446be05292e3e1f8a51218827168cdclaireho 4165569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 4175569331642446be05292e3e1f8a51218827168cdclaireho { 4185569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 4195569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 4205569331642446be05292e3e1f8a51218827168cdclaireho 4215569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 4225569331642446be05292e3e1f8a51218827168cdclaireho 4235569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 4245569331642446be05292e3e1f8a51218827168cdclaireho 4255569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 4265569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 4275569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_Sequence( &s[n], stream ) ) != HB_Err_Ok ) 4285569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 4295569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 4305569331642446be05292e3e1f8a51218827168cdclaireho } 4315569331642446be05292e3e1f8a51218827168cdclaireho 4325569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 4335569331642446be05292e3e1f8a51218827168cdclaireho 4345569331642446be05292e3e1f8a51218827168cdclairehoFail1: 4355569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; m++ ) 4365569331642446be05292e3e1f8a51218827168cdclaireho Free_Sequence( &s[m] ); 4375569331642446be05292e3e1f8a51218827168cdclaireho 4385569331642446be05292e3e1f8a51218827168cdclaireho FREE( s ); 4395569331642446be05292e3e1f8a51218827168cdclaireho 4405569331642446be05292e3e1f8a51218827168cdclairehoFail2: 4415569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &ms->Coverage ); 4425569331642446be05292e3e1f8a51218827168cdclaireho return error; 4435569331642446be05292e3e1f8a51218827168cdclaireho} 4445569331642446be05292e3e1f8a51218827168cdclaireho 4455569331642446be05292e3e1f8a51218827168cdclaireho 4465569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_MultipleSubst( HB_GSUB_SubTable* st ) 4475569331642446be05292e3e1f8a51218827168cdclaireho{ 4485569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 4495569331642446be05292e3e1f8a51218827168cdclaireho HB_MultipleSubst* ms = &st->multiple; 4505569331642446be05292e3e1f8a51218827168cdclaireho 4515569331642446be05292e3e1f8a51218827168cdclaireho HB_Sequence* s; 4525569331642446be05292e3e1f8a51218827168cdclaireho 4535569331642446be05292e3e1f8a51218827168cdclaireho 4545569331642446be05292e3e1f8a51218827168cdclaireho if ( ms->Sequence ) 4555569331642446be05292e3e1f8a51218827168cdclaireho { 4565569331642446be05292e3e1f8a51218827168cdclaireho count = ms->SequenceCount; 4575569331642446be05292e3e1f8a51218827168cdclaireho s = ms->Sequence; 4585569331642446be05292e3e1f8a51218827168cdclaireho 4595569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 4605569331642446be05292e3e1f8a51218827168cdclaireho Free_Sequence( &s[n] ); 4615569331642446be05292e3e1f8a51218827168cdclaireho 4625569331642446be05292e3e1f8a51218827168cdclaireho FREE( s ); 4635569331642446be05292e3e1f8a51218827168cdclaireho } 4645569331642446be05292e3e1f8a51218827168cdclaireho 4655569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &ms->Coverage ); 4665569331642446be05292e3e1f8a51218827168cdclaireho} 4675569331642446be05292e3e1f8a51218827168cdclaireho 4685569331642446be05292e3e1f8a51218827168cdclaireho 4695569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Lookup_MultipleSubst( HB_GSUBHeader* gsub, 4705569331642446be05292e3e1f8a51218827168cdclaireho HB_GSUB_SubTable* st, 4715569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 4725569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort flags, 4735569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 4745569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 4755569331642446be05292e3e1f8a51218827168cdclaireho{ 4765569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 4775569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort index, property, n, count; 4785569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort*s; 4795569331642446be05292e3e1f8a51218827168cdclaireho HB_MultipleSubst* ms = &st->multiple; 4805569331642446be05292e3e1f8a51218827168cdclaireho HB_GDEFHeader* gdef = gsub->gdef; 4815569331642446be05292e3e1f8a51218827168cdclaireho 4825569331642446be05292e3e1f8a51218827168cdclaireho HB_UNUSED(nesting_level); 4835569331642446be05292e3e1f8a51218827168cdclaireho 4845569331642446be05292e3e1f8a51218827168cdclaireho if ( context_length != 0xFFFF && context_length < 1 ) 4855569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 4865569331642446be05292e3e1f8a51218827168cdclaireho 4875569331642446be05292e3e1f8a51218827168cdclaireho if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) 4885569331642446be05292e3e1f8a51218827168cdclaireho return error; 4895569331642446be05292e3e1f8a51218827168cdclaireho 4905569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &ms->Coverage, IN_CURGLYPH(), &index ); 4915569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 4925569331642446be05292e3e1f8a51218827168cdclaireho return error; 4935569331642446be05292e3e1f8a51218827168cdclaireho 4945569331642446be05292e3e1f8a51218827168cdclaireho if ( index >= ms->SequenceCount ) 4955569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable); 4965569331642446be05292e3e1f8a51218827168cdclaireho 4975569331642446be05292e3e1f8a51218827168cdclaireho count = ms->Sequence[index].GlyphCount; 4985569331642446be05292e3e1f8a51218827168cdclaireho s = ms->Sequence[index].Substitute; 4995569331642446be05292e3e1f8a51218827168cdclaireho 5005569331642446be05292e3e1f8a51218827168cdclaireho if ( ADD_String( buffer, 1, count, s, 0xFFFF, 0xFFFF ) ) 5015569331642446be05292e3e1f8a51218827168cdclaireho return error; 5025569331642446be05292e3e1f8a51218827168cdclaireho 5035569331642446be05292e3e1f8a51218827168cdclaireho if ( gdef && gdef->NewGlyphClasses ) 5045569331642446be05292e3e1f8a51218827168cdclaireho { 5055569331642446be05292e3e1f8a51218827168cdclaireho /* this is a guess only ... */ 5065569331642446be05292e3e1f8a51218827168cdclaireho 5075569331642446be05292e3e1f8a51218827168cdclaireho if ( property == HB_GDEF_LIGATURE ) 5085569331642446be05292e3e1f8a51218827168cdclaireho property = HB_GDEF_BASE_GLYPH; 5095569331642446be05292e3e1f8a51218827168cdclaireho 5105569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 5115569331642446be05292e3e1f8a51218827168cdclaireho { 5125569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_GDEF_Add_Glyph_Property( gdef, s[n], property ); 5135569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 5145569331642446be05292e3e1f8a51218827168cdclaireho return error; 5155569331642446be05292e3e1f8a51218827168cdclaireho } 5165569331642446be05292e3e1f8a51218827168cdclaireho } 5175569331642446be05292e3e1f8a51218827168cdclaireho 5185569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 5195569331642446be05292e3e1f8a51218827168cdclaireho} 5205569331642446be05292e3e1f8a51218827168cdclaireho 5215569331642446be05292e3e1f8a51218827168cdclaireho 5225569331642446be05292e3e1f8a51218827168cdclaireho/* LookupType 3 */ 5235569331642446be05292e3e1f8a51218827168cdclaireho 5245569331642446be05292e3e1f8a51218827168cdclaireho/* AlternateSet */ 5255569331642446be05292e3e1f8a51218827168cdclaireho 5265569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_AlternateSet( HB_AlternateSet* as, 5275569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 5285569331642446be05292e3e1f8a51218827168cdclaireho{ 5295569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 5305569331642446be05292e3e1f8a51218827168cdclaireho 5315569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 5325569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* a; 5335569331642446be05292e3e1f8a51218827168cdclaireho 5345569331642446be05292e3e1f8a51218827168cdclaireho 5355569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 5365569331642446be05292e3e1f8a51218827168cdclaireho return error; 5375569331642446be05292e3e1f8a51218827168cdclaireho 5385569331642446be05292e3e1f8a51218827168cdclaireho count = as->GlyphCount = GET_UShort(); 5395569331642446be05292e3e1f8a51218827168cdclaireho 5405569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 5415569331642446be05292e3e1f8a51218827168cdclaireho 5425569331642446be05292e3e1f8a51218827168cdclaireho as->Alternate = NULL; 5435569331642446be05292e3e1f8a51218827168cdclaireho 5445569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( as->Alternate, count, HB_UShort ) ) 5455569331642446be05292e3e1f8a51218827168cdclaireho return error; 5465569331642446be05292e3e1f8a51218827168cdclaireho 5475569331642446be05292e3e1f8a51218827168cdclaireho a = as->Alternate; 5485569331642446be05292e3e1f8a51218827168cdclaireho 5495569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 2L ) ) 5505569331642446be05292e3e1f8a51218827168cdclaireho { 5515569331642446be05292e3e1f8a51218827168cdclaireho FREE( a ); 5525569331642446be05292e3e1f8a51218827168cdclaireho return error; 5535569331642446be05292e3e1f8a51218827168cdclaireho } 5545569331642446be05292e3e1f8a51218827168cdclaireho 5555569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 5565569331642446be05292e3e1f8a51218827168cdclaireho a[n] = GET_UShort(); 5575569331642446be05292e3e1f8a51218827168cdclaireho 5585569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 5595569331642446be05292e3e1f8a51218827168cdclaireho 5605569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 5615569331642446be05292e3e1f8a51218827168cdclaireho} 5625569331642446be05292e3e1f8a51218827168cdclaireho 5635569331642446be05292e3e1f8a51218827168cdclaireho 5645569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_AlternateSet( HB_AlternateSet* as ) 5655569331642446be05292e3e1f8a51218827168cdclaireho{ 5665569331642446be05292e3e1f8a51218827168cdclaireho FREE( as->Alternate ); 5675569331642446be05292e3e1f8a51218827168cdclaireho} 5685569331642446be05292e3e1f8a51218827168cdclaireho 5695569331642446be05292e3e1f8a51218827168cdclaireho 5705569331642446be05292e3e1f8a51218827168cdclaireho/* AlternateSubstFormat1 */ 5715569331642446be05292e3e1f8a51218827168cdclaireho 5725569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_AlternateSubst( HB_GSUB_SubTable* st, 5735569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 5745569331642446be05292e3e1f8a51218827168cdclaireho{ 5755569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 5765569331642446be05292e3e1f8a51218827168cdclaireho HB_AlternateSubst* as = &st->alternate; 5775569331642446be05292e3e1f8a51218827168cdclaireho 5785569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n = 0, m, count; 5795569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 5805569331642446be05292e3e1f8a51218827168cdclaireho 5815569331642446be05292e3e1f8a51218827168cdclaireho HB_AlternateSet* aset; 5825569331642446be05292e3e1f8a51218827168cdclaireho 5835569331642446be05292e3e1f8a51218827168cdclaireho 5845569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 5855569331642446be05292e3e1f8a51218827168cdclaireho 5865569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 4L ) ) 5875569331642446be05292e3e1f8a51218827168cdclaireho return error; 5885569331642446be05292e3e1f8a51218827168cdclaireho 5895569331642446be05292e3e1f8a51218827168cdclaireho as->SubstFormat = GET_UShort(); /* should be 1 */ 5905569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 5915569331642446be05292e3e1f8a51218827168cdclaireho 5925569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 5935569331642446be05292e3e1f8a51218827168cdclaireho 5945569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 5955569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 5965569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &as->Coverage, stream ) ) != HB_Err_Ok ) 5975569331642446be05292e3e1f8a51218827168cdclaireho return error; 5985569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 5995569331642446be05292e3e1f8a51218827168cdclaireho 6005569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 6015569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 6025569331642446be05292e3e1f8a51218827168cdclaireho 6035569331642446be05292e3e1f8a51218827168cdclaireho count = as->AlternateSetCount = GET_UShort(); 6045569331642446be05292e3e1f8a51218827168cdclaireho 6055569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 6065569331642446be05292e3e1f8a51218827168cdclaireho 6075569331642446be05292e3e1f8a51218827168cdclaireho as->AlternateSet = NULL; 6085569331642446be05292e3e1f8a51218827168cdclaireho 6095569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( as->AlternateSet, count, HB_AlternateSet ) ) 6105569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 6115569331642446be05292e3e1f8a51218827168cdclaireho 6125569331642446be05292e3e1f8a51218827168cdclaireho aset = as->AlternateSet; 6135569331642446be05292e3e1f8a51218827168cdclaireho 6145569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 6155569331642446be05292e3e1f8a51218827168cdclaireho { 6165569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 6175569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 6185569331642446be05292e3e1f8a51218827168cdclaireho 6195569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 6205569331642446be05292e3e1f8a51218827168cdclaireho 6215569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 6225569331642446be05292e3e1f8a51218827168cdclaireho 6235569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 6245569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 6255569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_AlternateSet( &aset[n], stream ) ) != HB_Err_Ok ) 6265569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 6275569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 6285569331642446be05292e3e1f8a51218827168cdclaireho } 6295569331642446be05292e3e1f8a51218827168cdclaireho 6305569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 6315569331642446be05292e3e1f8a51218827168cdclaireho 6325569331642446be05292e3e1f8a51218827168cdclairehoFail1: 6335569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; m++ ) 6345569331642446be05292e3e1f8a51218827168cdclaireho Free_AlternateSet( &aset[m] ); 6355569331642446be05292e3e1f8a51218827168cdclaireho 6365569331642446be05292e3e1f8a51218827168cdclaireho FREE( aset ); 6375569331642446be05292e3e1f8a51218827168cdclaireho 6385569331642446be05292e3e1f8a51218827168cdclairehoFail2: 6395569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &as->Coverage ); 6405569331642446be05292e3e1f8a51218827168cdclaireho return error; 6415569331642446be05292e3e1f8a51218827168cdclaireho} 6425569331642446be05292e3e1f8a51218827168cdclaireho 6435569331642446be05292e3e1f8a51218827168cdclaireho 6445569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_AlternateSubst( HB_GSUB_SubTable* st ) 6455569331642446be05292e3e1f8a51218827168cdclaireho{ 6465569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 6475569331642446be05292e3e1f8a51218827168cdclaireho HB_AlternateSubst* as = &st->alternate; 6485569331642446be05292e3e1f8a51218827168cdclaireho 6495569331642446be05292e3e1f8a51218827168cdclaireho HB_AlternateSet* aset; 6505569331642446be05292e3e1f8a51218827168cdclaireho 6515569331642446be05292e3e1f8a51218827168cdclaireho 6525569331642446be05292e3e1f8a51218827168cdclaireho if ( as->AlternateSet ) 6535569331642446be05292e3e1f8a51218827168cdclaireho { 6545569331642446be05292e3e1f8a51218827168cdclaireho count = as->AlternateSetCount; 6555569331642446be05292e3e1f8a51218827168cdclaireho aset = as->AlternateSet; 6565569331642446be05292e3e1f8a51218827168cdclaireho 6575569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 6585569331642446be05292e3e1f8a51218827168cdclaireho Free_AlternateSet( &aset[n] ); 6595569331642446be05292e3e1f8a51218827168cdclaireho 6605569331642446be05292e3e1f8a51218827168cdclaireho FREE( aset ); 6615569331642446be05292e3e1f8a51218827168cdclaireho } 6625569331642446be05292e3e1f8a51218827168cdclaireho 6635569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &as->Coverage ); 6645569331642446be05292e3e1f8a51218827168cdclaireho} 6655569331642446be05292e3e1f8a51218827168cdclaireho 6665569331642446be05292e3e1f8a51218827168cdclaireho 6675569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Lookup_AlternateSubst( HB_GSUBHeader* gsub, 6685569331642446be05292e3e1f8a51218827168cdclaireho HB_GSUB_SubTable* st, 6695569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 6705569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort flags, 6715569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 6725569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 6735569331642446be05292e3e1f8a51218827168cdclaireho{ 6745569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 6755569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort index, value, alt_index, property; 6765569331642446be05292e3e1f8a51218827168cdclaireho HB_AlternateSubst* as = &st->alternate; 6775569331642446be05292e3e1f8a51218827168cdclaireho HB_GDEFHeader* gdef = gsub->gdef; 6785569331642446be05292e3e1f8a51218827168cdclaireho HB_AlternateSet aset; 6795569331642446be05292e3e1f8a51218827168cdclaireho 6805569331642446be05292e3e1f8a51218827168cdclaireho HB_UNUSED(nesting_level); 6815569331642446be05292e3e1f8a51218827168cdclaireho 6825569331642446be05292e3e1f8a51218827168cdclaireho if ( context_length != 0xFFFF && context_length < 1 ) 6835569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 6845569331642446be05292e3e1f8a51218827168cdclaireho 6855569331642446be05292e3e1f8a51218827168cdclaireho if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) 6865569331642446be05292e3e1f8a51218827168cdclaireho return error; 6875569331642446be05292e3e1f8a51218827168cdclaireho 6885569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &as->Coverage, IN_CURGLYPH(), &index ); 6895569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 6905569331642446be05292e3e1f8a51218827168cdclaireho return error; 6915569331642446be05292e3e1f8a51218827168cdclaireho 6925569331642446be05292e3e1f8a51218827168cdclaireho aset = as->AlternateSet[index]; 6935569331642446be05292e3e1f8a51218827168cdclaireho 6945569331642446be05292e3e1f8a51218827168cdclaireho /* we use a user-defined callback function to get the alternate index */ 6955569331642446be05292e3e1f8a51218827168cdclaireho 6965569331642446be05292e3e1f8a51218827168cdclaireho if ( gsub->altfunc ) 6975569331642446be05292e3e1f8a51218827168cdclaireho alt_index = (gsub->altfunc)( buffer->out_pos, IN_CURGLYPH(), 6985569331642446be05292e3e1f8a51218827168cdclaireho aset.GlyphCount, aset.Alternate, 6995569331642446be05292e3e1f8a51218827168cdclaireho gsub->data ); 7005569331642446be05292e3e1f8a51218827168cdclaireho else 7015569331642446be05292e3e1f8a51218827168cdclaireho alt_index = 0; 7025569331642446be05292e3e1f8a51218827168cdclaireho 7035569331642446be05292e3e1f8a51218827168cdclaireho value = aset.Alternate[alt_index]; 7045569331642446be05292e3e1f8a51218827168cdclaireho if ( REPLACE_Glyph( buffer, value, nesting_level ) ) 7055569331642446be05292e3e1f8a51218827168cdclaireho return error; 7065569331642446be05292e3e1f8a51218827168cdclaireho 7075569331642446be05292e3e1f8a51218827168cdclaireho if ( gdef && gdef->NewGlyphClasses ) 7085569331642446be05292e3e1f8a51218827168cdclaireho { 7095569331642446be05292e3e1f8a51218827168cdclaireho /* we inherit the old glyph class to the substituted glyph */ 7105569331642446be05292e3e1f8a51218827168cdclaireho 7115569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_GDEF_Add_Glyph_Property( gdef, value, property ); 7125569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 7135569331642446be05292e3e1f8a51218827168cdclaireho return error; 7145569331642446be05292e3e1f8a51218827168cdclaireho } 7155569331642446be05292e3e1f8a51218827168cdclaireho 7165569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 7175569331642446be05292e3e1f8a51218827168cdclaireho} 7185569331642446be05292e3e1f8a51218827168cdclaireho 7195569331642446be05292e3e1f8a51218827168cdclaireho 7205569331642446be05292e3e1f8a51218827168cdclaireho/* LookupType 4 */ 7215569331642446be05292e3e1f8a51218827168cdclaireho 7225569331642446be05292e3e1f8a51218827168cdclaireho/* Ligature */ 7235569331642446be05292e3e1f8a51218827168cdclaireho 7245569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_Ligature( HB_Ligature* l, 7255569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 7265569331642446be05292e3e1f8a51218827168cdclaireho{ 7275569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 7285569331642446be05292e3e1f8a51218827168cdclaireho 7295569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 7305569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* c; 7315569331642446be05292e3e1f8a51218827168cdclaireho 7325569331642446be05292e3e1f8a51218827168cdclaireho 7335569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 4L ) ) 7345569331642446be05292e3e1f8a51218827168cdclaireho return error; 7355569331642446be05292e3e1f8a51218827168cdclaireho 7365569331642446be05292e3e1f8a51218827168cdclaireho l->LigGlyph = GET_UShort(); 7375569331642446be05292e3e1f8a51218827168cdclaireho l->ComponentCount = GET_UShort(); 7385569331642446be05292e3e1f8a51218827168cdclaireho 7395569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 7405569331642446be05292e3e1f8a51218827168cdclaireho 7415569331642446be05292e3e1f8a51218827168cdclaireho l->Component = NULL; 7425569331642446be05292e3e1f8a51218827168cdclaireho 7435569331642446be05292e3e1f8a51218827168cdclaireho count = l->ComponentCount - 1; /* only ComponentCount - 1 elements */ 7445569331642446be05292e3e1f8a51218827168cdclaireho 7455569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( l->Component, count, HB_UShort ) ) 7465569331642446be05292e3e1f8a51218827168cdclaireho return error; 7475569331642446be05292e3e1f8a51218827168cdclaireho 7485569331642446be05292e3e1f8a51218827168cdclaireho c = l->Component; 7495569331642446be05292e3e1f8a51218827168cdclaireho 7505569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 2L ) ) 7515569331642446be05292e3e1f8a51218827168cdclaireho { 7525569331642446be05292e3e1f8a51218827168cdclaireho FREE( c ); 7535569331642446be05292e3e1f8a51218827168cdclaireho return error; 7545569331642446be05292e3e1f8a51218827168cdclaireho } 7555569331642446be05292e3e1f8a51218827168cdclaireho 7565569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 7575569331642446be05292e3e1f8a51218827168cdclaireho c[n] = GET_UShort(); 7585569331642446be05292e3e1f8a51218827168cdclaireho 7595569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 7605569331642446be05292e3e1f8a51218827168cdclaireho 7615569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 7625569331642446be05292e3e1f8a51218827168cdclaireho} 7635569331642446be05292e3e1f8a51218827168cdclaireho 7645569331642446be05292e3e1f8a51218827168cdclaireho 7655569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_Ligature( HB_Ligature* l ) 7665569331642446be05292e3e1f8a51218827168cdclaireho{ 7675569331642446be05292e3e1f8a51218827168cdclaireho FREE( l->Component ); 7685569331642446be05292e3e1f8a51218827168cdclaireho} 7695569331642446be05292e3e1f8a51218827168cdclaireho 7705569331642446be05292e3e1f8a51218827168cdclaireho 7715569331642446be05292e3e1f8a51218827168cdclaireho/* LigatureSet */ 7725569331642446be05292e3e1f8a51218827168cdclaireho 7735569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_LigatureSet( HB_LigatureSet* ls, 7745569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 7755569331642446be05292e3e1f8a51218827168cdclaireho{ 7765569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 7775569331642446be05292e3e1f8a51218827168cdclaireho 7785569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n = 0, m, count; 7795569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 7805569331642446be05292e3e1f8a51218827168cdclaireho 7815569331642446be05292e3e1f8a51218827168cdclaireho HB_Ligature* l; 7825569331642446be05292e3e1f8a51218827168cdclaireho 7835569331642446be05292e3e1f8a51218827168cdclaireho 7845569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 7855569331642446be05292e3e1f8a51218827168cdclaireho 7865569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 7875569331642446be05292e3e1f8a51218827168cdclaireho return error; 7885569331642446be05292e3e1f8a51218827168cdclaireho 7895569331642446be05292e3e1f8a51218827168cdclaireho count = ls->LigatureCount = GET_UShort(); 7905569331642446be05292e3e1f8a51218827168cdclaireho 7915569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 7925569331642446be05292e3e1f8a51218827168cdclaireho 7935569331642446be05292e3e1f8a51218827168cdclaireho ls->Ligature = NULL; 7945569331642446be05292e3e1f8a51218827168cdclaireho 7955569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( ls->Ligature, count, HB_Ligature ) ) 7965569331642446be05292e3e1f8a51218827168cdclaireho return error; 7975569331642446be05292e3e1f8a51218827168cdclaireho 7985569331642446be05292e3e1f8a51218827168cdclaireho l = ls->Ligature; 7995569331642446be05292e3e1f8a51218827168cdclaireho 8005569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 8015569331642446be05292e3e1f8a51218827168cdclaireho { 8025569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 8035569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 8045569331642446be05292e3e1f8a51218827168cdclaireho 8055569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 8065569331642446be05292e3e1f8a51218827168cdclaireho 8075569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 8085569331642446be05292e3e1f8a51218827168cdclaireho 8095569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 8105569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 8115569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_Ligature( &l[n], stream ) ) != HB_Err_Ok ) 8125569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 8135569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 8145569331642446be05292e3e1f8a51218827168cdclaireho } 8155569331642446be05292e3e1f8a51218827168cdclaireho 8165569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 8175569331642446be05292e3e1f8a51218827168cdclaireho 8185569331642446be05292e3e1f8a51218827168cdclairehoFail: 8195569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; m++ ) 8205569331642446be05292e3e1f8a51218827168cdclaireho Free_Ligature( &l[m] ); 8215569331642446be05292e3e1f8a51218827168cdclaireho 8225569331642446be05292e3e1f8a51218827168cdclaireho FREE( l ); 8235569331642446be05292e3e1f8a51218827168cdclaireho return error; 8245569331642446be05292e3e1f8a51218827168cdclaireho} 8255569331642446be05292e3e1f8a51218827168cdclaireho 8265569331642446be05292e3e1f8a51218827168cdclaireho 8275569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_LigatureSet( HB_LigatureSet* ls ) 8285569331642446be05292e3e1f8a51218827168cdclaireho{ 8295569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 8305569331642446be05292e3e1f8a51218827168cdclaireho 8315569331642446be05292e3e1f8a51218827168cdclaireho HB_Ligature* l; 8325569331642446be05292e3e1f8a51218827168cdclaireho 8335569331642446be05292e3e1f8a51218827168cdclaireho 8345569331642446be05292e3e1f8a51218827168cdclaireho if ( ls->Ligature ) 8355569331642446be05292e3e1f8a51218827168cdclaireho { 8365569331642446be05292e3e1f8a51218827168cdclaireho count = ls->LigatureCount; 8375569331642446be05292e3e1f8a51218827168cdclaireho l = ls->Ligature; 8385569331642446be05292e3e1f8a51218827168cdclaireho 8395569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 8405569331642446be05292e3e1f8a51218827168cdclaireho Free_Ligature( &l[n] ); 8415569331642446be05292e3e1f8a51218827168cdclaireho 8425569331642446be05292e3e1f8a51218827168cdclaireho FREE( l ); 8435569331642446be05292e3e1f8a51218827168cdclaireho } 8445569331642446be05292e3e1f8a51218827168cdclaireho} 8455569331642446be05292e3e1f8a51218827168cdclaireho 8465569331642446be05292e3e1f8a51218827168cdclaireho 8475569331642446be05292e3e1f8a51218827168cdclaireho/* LigatureSubstFormat1 */ 8485569331642446be05292e3e1f8a51218827168cdclaireho 8495569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_LigatureSubst( HB_GSUB_SubTable* st, 8505569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 8515569331642446be05292e3e1f8a51218827168cdclaireho{ 8525569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 8535569331642446be05292e3e1f8a51218827168cdclaireho HB_LigatureSubst* ls = &st->ligature; 8545569331642446be05292e3e1f8a51218827168cdclaireho 8555569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n = 0, m, count; 8565569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 8575569331642446be05292e3e1f8a51218827168cdclaireho 8585569331642446be05292e3e1f8a51218827168cdclaireho HB_LigatureSet* lset; 8595569331642446be05292e3e1f8a51218827168cdclaireho 8605569331642446be05292e3e1f8a51218827168cdclaireho 8615569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 8625569331642446be05292e3e1f8a51218827168cdclaireho 8635569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 4L ) ) 8645569331642446be05292e3e1f8a51218827168cdclaireho return error; 8655569331642446be05292e3e1f8a51218827168cdclaireho 8665569331642446be05292e3e1f8a51218827168cdclaireho ls->SubstFormat = GET_UShort(); /* should be 1 */ 8675569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 8685569331642446be05292e3e1f8a51218827168cdclaireho 8695569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 8705569331642446be05292e3e1f8a51218827168cdclaireho 8715569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 8725569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 8735569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &ls->Coverage, stream ) ) != HB_Err_Ok ) 8745569331642446be05292e3e1f8a51218827168cdclaireho return error; 8755569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 8765569331642446be05292e3e1f8a51218827168cdclaireho 8775569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 8785569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 8795569331642446be05292e3e1f8a51218827168cdclaireho 8805569331642446be05292e3e1f8a51218827168cdclaireho count = ls->LigatureSetCount = GET_UShort(); 8815569331642446be05292e3e1f8a51218827168cdclaireho 8825569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 8835569331642446be05292e3e1f8a51218827168cdclaireho 8845569331642446be05292e3e1f8a51218827168cdclaireho ls->LigatureSet = NULL; 8855569331642446be05292e3e1f8a51218827168cdclaireho 8865569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( ls->LigatureSet, count, HB_LigatureSet ) ) 8875569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 8885569331642446be05292e3e1f8a51218827168cdclaireho 8895569331642446be05292e3e1f8a51218827168cdclaireho lset = ls->LigatureSet; 8905569331642446be05292e3e1f8a51218827168cdclaireho 8915569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 8925569331642446be05292e3e1f8a51218827168cdclaireho { 8935569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 8945569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 8955569331642446be05292e3e1f8a51218827168cdclaireho 8965569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 8975569331642446be05292e3e1f8a51218827168cdclaireho 8985569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 8995569331642446be05292e3e1f8a51218827168cdclaireho 9005569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 9015569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 9025569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_LigatureSet( &lset[n], stream ) ) != HB_Err_Ok ) 9035569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 9045569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 9055569331642446be05292e3e1f8a51218827168cdclaireho } 9065569331642446be05292e3e1f8a51218827168cdclaireho 9075569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 9085569331642446be05292e3e1f8a51218827168cdclaireho 9095569331642446be05292e3e1f8a51218827168cdclairehoFail1: 9105569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; m++ ) 9115569331642446be05292e3e1f8a51218827168cdclaireho Free_LigatureSet( &lset[m] ); 9125569331642446be05292e3e1f8a51218827168cdclaireho 9135569331642446be05292e3e1f8a51218827168cdclaireho FREE( lset ); 9145569331642446be05292e3e1f8a51218827168cdclaireho 9155569331642446be05292e3e1f8a51218827168cdclairehoFail2: 9165569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &ls->Coverage ); 9175569331642446be05292e3e1f8a51218827168cdclaireho return error; 9185569331642446be05292e3e1f8a51218827168cdclaireho} 9195569331642446be05292e3e1f8a51218827168cdclaireho 9205569331642446be05292e3e1f8a51218827168cdclaireho 9215569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_LigatureSubst( HB_GSUB_SubTable* st ) 9225569331642446be05292e3e1f8a51218827168cdclaireho{ 9235569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 9245569331642446be05292e3e1f8a51218827168cdclaireho HB_LigatureSubst* ls = &st->ligature; 9255569331642446be05292e3e1f8a51218827168cdclaireho 9265569331642446be05292e3e1f8a51218827168cdclaireho HB_LigatureSet* lset; 9275569331642446be05292e3e1f8a51218827168cdclaireho 9285569331642446be05292e3e1f8a51218827168cdclaireho 9295569331642446be05292e3e1f8a51218827168cdclaireho if ( ls->LigatureSet ) 9305569331642446be05292e3e1f8a51218827168cdclaireho { 9315569331642446be05292e3e1f8a51218827168cdclaireho count = ls->LigatureSetCount; 9325569331642446be05292e3e1f8a51218827168cdclaireho lset = ls->LigatureSet; 9335569331642446be05292e3e1f8a51218827168cdclaireho 9345569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 9355569331642446be05292e3e1f8a51218827168cdclaireho Free_LigatureSet( &lset[n] ); 9365569331642446be05292e3e1f8a51218827168cdclaireho 9375569331642446be05292e3e1f8a51218827168cdclaireho FREE( lset ); 9385569331642446be05292e3e1f8a51218827168cdclaireho } 9395569331642446be05292e3e1f8a51218827168cdclaireho 9405569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &ls->Coverage ); 9415569331642446be05292e3e1f8a51218827168cdclaireho} 9425569331642446be05292e3e1f8a51218827168cdclaireho 9435569331642446be05292e3e1f8a51218827168cdclaireho 9445569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Lookup_LigatureSubst( HB_GSUBHeader* gsub, 9455569331642446be05292e3e1f8a51218827168cdclaireho HB_GSUB_SubTable* st, 9465569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 9475569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort flags, 9485569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 9495569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 9505569331642446be05292e3e1f8a51218827168cdclaireho{ 9515569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort index, property; 9525569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 9535569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort numlig, i, j, is_mark, first_is_mark = FALSE; 9545569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* c; 9555569331642446be05292e3e1f8a51218827168cdclaireho HB_LigatureSubst* ls = &st->ligature; 9565569331642446be05292e3e1f8a51218827168cdclaireho HB_GDEFHeader* gdef = gsub->gdef; 9575569331642446be05292e3e1f8a51218827168cdclaireho 9585569331642446be05292e3e1f8a51218827168cdclaireho HB_Ligature* lig; 9595569331642446be05292e3e1f8a51218827168cdclaireho 9605569331642446be05292e3e1f8a51218827168cdclaireho HB_UNUSED(nesting_level); 9615569331642446be05292e3e1f8a51218827168cdclaireho 9625569331642446be05292e3e1f8a51218827168cdclaireho if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) 9635569331642446be05292e3e1f8a51218827168cdclaireho return error; 9645569331642446be05292e3e1f8a51218827168cdclaireho 9655569331642446be05292e3e1f8a51218827168cdclaireho if ( property == HB_GDEF_MARK || property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) 9665569331642446be05292e3e1f8a51218827168cdclaireho first_is_mark = TRUE; 9675569331642446be05292e3e1f8a51218827168cdclaireho 9685569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &ls->Coverage, IN_CURGLYPH(), &index ); 9695569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 9705569331642446be05292e3e1f8a51218827168cdclaireho return error; 9715569331642446be05292e3e1f8a51218827168cdclaireho 9725569331642446be05292e3e1f8a51218827168cdclaireho if ( index >= ls->LigatureSetCount ) 9735569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable); 9745569331642446be05292e3e1f8a51218827168cdclaireho 9755569331642446be05292e3e1f8a51218827168cdclaireho lig = ls->LigatureSet[index].Ligature; 9765569331642446be05292e3e1f8a51218827168cdclaireho 9775569331642446be05292e3e1f8a51218827168cdclaireho for ( numlig = ls->LigatureSet[index].LigatureCount; 9785569331642446be05292e3e1f8a51218827168cdclaireho numlig; 9795569331642446be05292e3e1f8a51218827168cdclaireho numlig--, lig++ ) 9805569331642446be05292e3e1f8a51218827168cdclaireho { 9815569331642446be05292e3e1f8a51218827168cdclaireho if ( buffer->in_pos + lig->ComponentCount > buffer->in_length ) 9825569331642446be05292e3e1f8a51218827168cdclaireho goto next_ligature; /* Not enough glyphs in input */ 9835569331642446be05292e3e1f8a51218827168cdclaireho 9845569331642446be05292e3e1f8a51218827168cdclaireho c = lig->Component; 9855569331642446be05292e3e1f8a51218827168cdclaireho 9865569331642446be05292e3e1f8a51218827168cdclaireho is_mark = first_is_mark; 9875569331642446be05292e3e1f8a51218827168cdclaireho 9885569331642446be05292e3e1f8a51218827168cdclaireho if ( context_length != 0xFFFF && context_length < lig->ComponentCount ) 9895569331642446be05292e3e1f8a51218827168cdclaireho break; 9905569331642446be05292e3e1f8a51218827168cdclaireho 9915569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 1, j = buffer->in_pos + 1; i < lig->ComponentCount; i++, j++ ) 9925569331642446be05292e3e1f8a51218827168cdclaireho { 9935569331642446be05292e3e1f8a51218827168cdclaireho while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) 9945569331642446be05292e3e1f8a51218827168cdclaireho { 9955569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 9965569331642446be05292e3e1f8a51218827168cdclaireho return error; 9975569331642446be05292e3e1f8a51218827168cdclaireho 9985569331642446be05292e3e1f8a51218827168cdclaireho if ( j + lig->ComponentCount - i == (HB_Int)buffer->in_length ) 9995569331642446be05292e3e1f8a51218827168cdclaireho goto next_ligature; 10005569331642446be05292e3e1f8a51218827168cdclaireho j++; 10015569331642446be05292e3e1f8a51218827168cdclaireho } 10025569331642446be05292e3e1f8a51218827168cdclaireho 10035569331642446be05292e3e1f8a51218827168cdclaireho if ( !( property == HB_GDEF_MARK || property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) ) 10045569331642446be05292e3e1f8a51218827168cdclaireho is_mark = FALSE; 10055569331642446be05292e3e1f8a51218827168cdclaireho 10065569331642446be05292e3e1f8a51218827168cdclaireho if ( IN_GLYPH( j ) != c[i - 1] ) 10075569331642446be05292e3e1f8a51218827168cdclaireho goto next_ligature; 10085569331642446be05292e3e1f8a51218827168cdclaireho } 10095569331642446be05292e3e1f8a51218827168cdclaireho 10105569331642446be05292e3e1f8a51218827168cdclaireho if ( gdef && gdef->NewGlyphClasses ) 10115569331642446be05292e3e1f8a51218827168cdclaireho { 10125569331642446be05292e3e1f8a51218827168cdclaireho /* this is just a guess ... */ 10135569331642446be05292e3e1f8a51218827168cdclaireho 10145569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_GDEF_Add_Glyph_Property( gdef, lig->LigGlyph, 10155569331642446be05292e3e1f8a51218827168cdclaireho is_mark ? HB_GDEF_MARK : HB_GDEF_LIGATURE ); 10165569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 10175569331642446be05292e3e1f8a51218827168cdclaireho return error; 10185569331642446be05292e3e1f8a51218827168cdclaireho } 10195569331642446be05292e3e1f8a51218827168cdclaireho 10205569331642446be05292e3e1f8a51218827168cdclaireho if ( j == buffer->in_pos + i ) /* No input glyphs skipped */ 10215569331642446be05292e3e1f8a51218827168cdclaireho { 10225569331642446be05292e3e1f8a51218827168cdclaireho /* We don't use a new ligature ID if there are no skipped 10235569331642446be05292e3e1f8a51218827168cdclaireho glyphs and the ligature already has an ID. */ 10245569331642446be05292e3e1f8a51218827168cdclaireho 10255569331642446be05292e3e1f8a51218827168cdclaireho if ( IN_LIGID( buffer->in_pos ) ) 10265569331642446be05292e3e1f8a51218827168cdclaireho { 10275569331642446be05292e3e1f8a51218827168cdclaireho if ( ADD_String( buffer, i, 1, &lig->LigGlyph, 10285569331642446be05292e3e1f8a51218827168cdclaireho 0xFFFF, 0xFFFF ) ) 10295569331642446be05292e3e1f8a51218827168cdclaireho return error; 10305569331642446be05292e3e1f8a51218827168cdclaireho } 10315569331642446be05292e3e1f8a51218827168cdclaireho else 10325569331642446be05292e3e1f8a51218827168cdclaireho { 10335569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort ligID = _hb_buffer_allocate_ligid( buffer ); 10345569331642446be05292e3e1f8a51218827168cdclaireho if ( ADD_String( buffer, i, 1, &lig->LigGlyph, 10355569331642446be05292e3e1f8a51218827168cdclaireho 0xFFFF, ligID ) ) 10365569331642446be05292e3e1f8a51218827168cdclaireho return error; 10375569331642446be05292e3e1f8a51218827168cdclaireho } 10385569331642446be05292e3e1f8a51218827168cdclaireho } 10395569331642446be05292e3e1f8a51218827168cdclaireho else 10405569331642446be05292e3e1f8a51218827168cdclaireho { 10415569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort ligID = _hb_buffer_allocate_ligid( buffer ); 10425569331642446be05292e3e1f8a51218827168cdclaireho if ( ADD_Glyph( buffer, lig->LigGlyph, 0xFFFF, ligID ) ) 10435569331642446be05292e3e1f8a51218827168cdclaireho return error; 10445569331642446be05292e3e1f8a51218827168cdclaireho 10455569331642446be05292e3e1f8a51218827168cdclaireho /* Now we must do a second loop to copy the skipped glyphs to 10465569331642446be05292e3e1f8a51218827168cdclaireho `out' and assign component values to it. We start with the 10475569331642446be05292e3e1f8a51218827168cdclaireho glyph after the first component. Glyphs between component 10485569331642446be05292e3e1f8a51218827168cdclaireho i and i+1 belong to component i. Together with the ligID 10495569331642446be05292e3e1f8a51218827168cdclaireho value it is later possible to check whether a specific 10505569331642446be05292e3e1f8a51218827168cdclaireho component value really belongs to a given ligature. */ 10515569331642446be05292e3e1f8a51218827168cdclaireho 10525569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 0; i < lig->ComponentCount - 1; i++ ) 10535569331642446be05292e3e1f8a51218827168cdclaireho { 10545569331642446be05292e3e1f8a51218827168cdclaireho while ( CHECK_Property( gdef, IN_CURITEM(), 10555569331642446be05292e3e1f8a51218827168cdclaireho flags, &property ) ) 10565569331642446be05292e3e1f8a51218827168cdclaireho if ( ADD_Glyph( buffer, IN_CURGLYPH(), i, ligID ) ) 10575569331642446be05292e3e1f8a51218827168cdclaireho return error; 10585569331642446be05292e3e1f8a51218827168cdclaireho 10595569331642446be05292e3e1f8a51218827168cdclaireho (buffer->in_pos)++; 10605569331642446be05292e3e1f8a51218827168cdclaireho } 10615569331642446be05292e3e1f8a51218827168cdclaireho } 10625569331642446be05292e3e1f8a51218827168cdclaireho 10635569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 10645569331642446be05292e3e1f8a51218827168cdclaireho 10655569331642446be05292e3e1f8a51218827168cdclaireho next_ligature: 10665569331642446be05292e3e1f8a51218827168cdclaireho ; 10675569331642446be05292e3e1f8a51218827168cdclaireho } 10685569331642446be05292e3e1f8a51218827168cdclaireho 10695569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 10705569331642446be05292e3e1f8a51218827168cdclaireho} 10715569331642446be05292e3e1f8a51218827168cdclaireho 10725569331642446be05292e3e1f8a51218827168cdclaireho 10735569331642446be05292e3e1f8a51218827168cdclaireho/* Do the actual substitution for a context substitution (either format 10745569331642446be05292e3e1f8a51218827168cdclaireho 5 or 6). This is only called after we've determined that the input 10755569331642446be05292e3e1f8a51218827168cdclaireho matches the subrule. */ 10765569331642446be05292e3e1f8a51218827168cdclaireho 10775569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Do_ContextSubst( HB_GSUBHeader* gsub, 10785569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort GlyphCount, 10795569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort SubstCount, 10805569331642446be05292e3e1f8a51218827168cdclaireho HB_SubstLookupRecord* subst, 10815569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 10825569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 10835569331642446be05292e3e1f8a51218827168cdclaireho{ 10845569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 10855569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt i, old_pos; 10865569331642446be05292e3e1f8a51218827168cdclaireho 10875569331642446be05292e3e1f8a51218827168cdclaireho 10885569331642446be05292e3e1f8a51218827168cdclaireho i = 0; 10895569331642446be05292e3e1f8a51218827168cdclaireho 10905569331642446be05292e3e1f8a51218827168cdclaireho while ( i < GlyphCount ) 10915569331642446be05292e3e1f8a51218827168cdclaireho { 10925569331642446be05292e3e1f8a51218827168cdclaireho if ( SubstCount && i == subst->SequenceIndex ) 10935569331642446be05292e3e1f8a51218827168cdclaireho { 10945569331642446be05292e3e1f8a51218827168cdclaireho old_pos = buffer->in_pos; 10955569331642446be05292e3e1f8a51218827168cdclaireho 10965569331642446be05292e3e1f8a51218827168cdclaireho /* Do a substitution */ 10975569331642446be05292e3e1f8a51218827168cdclaireho 10985569331642446be05292e3e1f8a51218827168cdclaireho error = GSUB_Do_Glyph_Lookup( gsub, subst->LookupListIndex, buffer, 10995569331642446be05292e3e1f8a51218827168cdclaireho GlyphCount, nesting_level ); 11005569331642446be05292e3e1f8a51218827168cdclaireho 11015569331642446be05292e3e1f8a51218827168cdclaireho subst++; 11025569331642446be05292e3e1f8a51218827168cdclaireho SubstCount--; 11035569331642446be05292e3e1f8a51218827168cdclaireho i += buffer->in_pos - old_pos; 11045569331642446be05292e3e1f8a51218827168cdclaireho 11055569331642446be05292e3e1f8a51218827168cdclaireho if ( error == HB_Err_Not_Covered ) 11065569331642446be05292e3e1f8a51218827168cdclaireho { 11075569331642446be05292e3e1f8a51218827168cdclaireho if ( COPY_Glyph( buffer ) ) 11085569331642446be05292e3e1f8a51218827168cdclaireho return error; 11095569331642446be05292e3e1f8a51218827168cdclaireho i++; 11105569331642446be05292e3e1f8a51218827168cdclaireho } 11115569331642446be05292e3e1f8a51218827168cdclaireho else if ( error ) 11125569331642446be05292e3e1f8a51218827168cdclaireho return error; 11135569331642446be05292e3e1f8a51218827168cdclaireho } 11145569331642446be05292e3e1f8a51218827168cdclaireho else 11155569331642446be05292e3e1f8a51218827168cdclaireho { 11165569331642446be05292e3e1f8a51218827168cdclaireho /* No substitution for this index */ 11175569331642446be05292e3e1f8a51218827168cdclaireho 11185569331642446be05292e3e1f8a51218827168cdclaireho if ( COPY_Glyph( buffer ) ) 11195569331642446be05292e3e1f8a51218827168cdclaireho return error; 11205569331642446be05292e3e1f8a51218827168cdclaireho i++; 11215569331642446be05292e3e1f8a51218827168cdclaireho } 11225569331642446be05292e3e1f8a51218827168cdclaireho } 11235569331642446be05292e3e1f8a51218827168cdclaireho 11245569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 11255569331642446be05292e3e1f8a51218827168cdclaireho} 11265569331642446be05292e3e1f8a51218827168cdclaireho 11275569331642446be05292e3e1f8a51218827168cdclaireho 11285569331642446be05292e3e1f8a51218827168cdclaireho/* LookupType 5 */ 11295569331642446be05292e3e1f8a51218827168cdclaireho 11305569331642446be05292e3e1f8a51218827168cdclaireho/* SubRule */ 11315569331642446be05292e3e1f8a51218827168cdclaireho 11325569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_SubRule( HB_SubRule* sr, 11335569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 11345569331642446be05292e3e1f8a51218827168cdclaireho{ 11355569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 11365569331642446be05292e3e1f8a51218827168cdclaireho 11375569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 11385569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* i; 11395569331642446be05292e3e1f8a51218827168cdclaireho 11405569331642446be05292e3e1f8a51218827168cdclaireho HB_SubstLookupRecord* slr; 11415569331642446be05292e3e1f8a51218827168cdclaireho 11425569331642446be05292e3e1f8a51218827168cdclaireho 11435569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 4L ) ) 11445569331642446be05292e3e1f8a51218827168cdclaireho return error; 11455569331642446be05292e3e1f8a51218827168cdclaireho 11465569331642446be05292e3e1f8a51218827168cdclaireho sr->GlyphCount = GET_UShort(); 11475569331642446be05292e3e1f8a51218827168cdclaireho sr->SubstCount = GET_UShort(); 11485569331642446be05292e3e1f8a51218827168cdclaireho 11495569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 11505569331642446be05292e3e1f8a51218827168cdclaireho 11515569331642446be05292e3e1f8a51218827168cdclaireho sr->Input = NULL; 11525569331642446be05292e3e1f8a51218827168cdclaireho 11535569331642446be05292e3e1f8a51218827168cdclaireho count = sr->GlyphCount - 1; /* only GlyphCount - 1 elements */ 11545569331642446be05292e3e1f8a51218827168cdclaireho 11555569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( sr->Input, count, HB_UShort ) ) 11565569331642446be05292e3e1f8a51218827168cdclaireho return error; 11575569331642446be05292e3e1f8a51218827168cdclaireho 11585569331642446be05292e3e1f8a51218827168cdclaireho i = sr->Input; 11595569331642446be05292e3e1f8a51218827168cdclaireho 11605569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 2L ) ) 11615569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 11625569331642446be05292e3e1f8a51218827168cdclaireho 11635569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 11645569331642446be05292e3e1f8a51218827168cdclaireho i[n] = GET_UShort(); 11655569331642446be05292e3e1f8a51218827168cdclaireho 11665569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 11675569331642446be05292e3e1f8a51218827168cdclaireho 11685569331642446be05292e3e1f8a51218827168cdclaireho sr->SubstLookupRecord = NULL; 11695569331642446be05292e3e1f8a51218827168cdclaireho 11705569331642446be05292e3e1f8a51218827168cdclaireho count = sr->SubstCount; 11715569331642446be05292e3e1f8a51218827168cdclaireho 11725569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( sr->SubstLookupRecord, count, HB_SubstLookupRecord ) ) 11735569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 11745569331642446be05292e3e1f8a51218827168cdclaireho 11755569331642446be05292e3e1f8a51218827168cdclaireho slr = sr->SubstLookupRecord; 11765569331642446be05292e3e1f8a51218827168cdclaireho 11775569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 4L ) ) 11785569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 11795569331642446be05292e3e1f8a51218827168cdclaireho 11805569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 11815569331642446be05292e3e1f8a51218827168cdclaireho { 11825569331642446be05292e3e1f8a51218827168cdclaireho slr[n].SequenceIndex = GET_UShort(); 11835569331642446be05292e3e1f8a51218827168cdclaireho slr[n].LookupListIndex = GET_UShort(); 11845569331642446be05292e3e1f8a51218827168cdclaireho } 11855569331642446be05292e3e1f8a51218827168cdclaireho 11865569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 11875569331642446be05292e3e1f8a51218827168cdclaireho 11885569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 11895569331642446be05292e3e1f8a51218827168cdclaireho 11905569331642446be05292e3e1f8a51218827168cdclairehoFail1: 11915569331642446be05292e3e1f8a51218827168cdclaireho FREE( slr ); 11925569331642446be05292e3e1f8a51218827168cdclaireho 11935569331642446be05292e3e1f8a51218827168cdclairehoFail2: 11945569331642446be05292e3e1f8a51218827168cdclaireho FREE( i ); 11955569331642446be05292e3e1f8a51218827168cdclaireho return error; 11965569331642446be05292e3e1f8a51218827168cdclaireho} 11975569331642446be05292e3e1f8a51218827168cdclaireho 11985569331642446be05292e3e1f8a51218827168cdclaireho 11995569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_SubRule( HB_SubRule* sr ) 12005569331642446be05292e3e1f8a51218827168cdclaireho{ 12015569331642446be05292e3e1f8a51218827168cdclaireho FREE( sr->SubstLookupRecord ); 12025569331642446be05292e3e1f8a51218827168cdclaireho FREE( sr->Input ); 12035569331642446be05292e3e1f8a51218827168cdclaireho} 12045569331642446be05292e3e1f8a51218827168cdclaireho 12055569331642446be05292e3e1f8a51218827168cdclaireho 12065569331642446be05292e3e1f8a51218827168cdclaireho/* SubRuleSet */ 12075569331642446be05292e3e1f8a51218827168cdclaireho 12085569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_SubRuleSet( HB_SubRuleSet* srs, 12095569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 12105569331642446be05292e3e1f8a51218827168cdclaireho{ 12115569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 12125569331642446be05292e3e1f8a51218827168cdclaireho 12135569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n = 0, m, count; 12145569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 12155569331642446be05292e3e1f8a51218827168cdclaireho 12165569331642446be05292e3e1f8a51218827168cdclaireho HB_SubRule* sr; 12175569331642446be05292e3e1f8a51218827168cdclaireho 12185569331642446be05292e3e1f8a51218827168cdclaireho 12195569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 12205569331642446be05292e3e1f8a51218827168cdclaireho 12215569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 12225569331642446be05292e3e1f8a51218827168cdclaireho return error; 12235569331642446be05292e3e1f8a51218827168cdclaireho 12245569331642446be05292e3e1f8a51218827168cdclaireho count = srs->SubRuleCount = GET_UShort(); 12255569331642446be05292e3e1f8a51218827168cdclaireho 12265569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 12275569331642446be05292e3e1f8a51218827168cdclaireho 12285569331642446be05292e3e1f8a51218827168cdclaireho srs->SubRule = NULL; 12295569331642446be05292e3e1f8a51218827168cdclaireho 12305569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( srs->SubRule, count, HB_SubRule ) ) 12315569331642446be05292e3e1f8a51218827168cdclaireho return error; 12325569331642446be05292e3e1f8a51218827168cdclaireho 12335569331642446be05292e3e1f8a51218827168cdclaireho sr = srs->SubRule; 12345569331642446be05292e3e1f8a51218827168cdclaireho 12355569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 12365569331642446be05292e3e1f8a51218827168cdclaireho { 12375569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 12385569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 12395569331642446be05292e3e1f8a51218827168cdclaireho 12405569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 12415569331642446be05292e3e1f8a51218827168cdclaireho 12425569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 12435569331642446be05292e3e1f8a51218827168cdclaireho 12445569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 12455569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 12465569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_SubRule( &sr[n], stream ) ) != HB_Err_Ok ) 12475569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 12485569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 12495569331642446be05292e3e1f8a51218827168cdclaireho } 12505569331642446be05292e3e1f8a51218827168cdclaireho 12515569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 12525569331642446be05292e3e1f8a51218827168cdclaireho 12535569331642446be05292e3e1f8a51218827168cdclairehoFail: 12545569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; m++ ) 12555569331642446be05292e3e1f8a51218827168cdclaireho Free_SubRule( &sr[m] ); 12565569331642446be05292e3e1f8a51218827168cdclaireho 12575569331642446be05292e3e1f8a51218827168cdclaireho FREE( sr ); 12585569331642446be05292e3e1f8a51218827168cdclaireho return error; 12595569331642446be05292e3e1f8a51218827168cdclaireho} 12605569331642446be05292e3e1f8a51218827168cdclaireho 12615569331642446be05292e3e1f8a51218827168cdclaireho 12625569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_SubRuleSet( HB_SubRuleSet* srs ) 12635569331642446be05292e3e1f8a51218827168cdclaireho{ 12645569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 12655569331642446be05292e3e1f8a51218827168cdclaireho 12665569331642446be05292e3e1f8a51218827168cdclaireho HB_SubRule* sr; 12675569331642446be05292e3e1f8a51218827168cdclaireho 12685569331642446be05292e3e1f8a51218827168cdclaireho 12695569331642446be05292e3e1f8a51218827168cdclaireho if ( srs->SubRule ) 12705569331642446be05292e3e1f8a51218827168cdclaireho { 12715569331642446be05292e3e1f8a51218827168cdclaireho count = srs->SubRuleCount; 12725569331642446be05292e3e1f8a51218827168cdclaireho sr = srs->SubRule; 12735569331642446be05292e3e1f8a51218827168cdclaireho 12745569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 12755569331642446be05292e3e1f8a51218827168cdclaireho Free_SubRule( &sr[n] ); 12765569331642446be05292e3e1f8a51218827168cdclaireho 12775569331642446be05292e3e1f8a51218827168cdclaireho FREE( sr ); 12785569331642446be05292e3e1f8a51218827168cdclaireho } 12795569331642446be05292e3e1f8a51218827168cdclaireho} 12805569331642446be05292e3e1f8a51218827168cdclaireho 12815569331642446be05292e3e1f8a51218827168cdclaireho 12825569331642446be05292e3e1f8a51218827168cdclaireho/* ContextSubstFormat1 */ 12835569331642446be05292e3e1f8a51218827168cdclaireho 12845569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_ContextSubst1( HB_ContextSubstFormat1* csf1, 12855569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 12865569331642446be05292e3e1f8a51218827168cdclaireho{ 12875569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 12885569331642446be05292e3e1f8a51218827168cdclaireho 12895569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n = 0, m, count; 12905569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 12915569331642446be05292e3e1f8a51218827168cdclaireho 12925569331642446be05292e3e1f8a51218827168cdclaireho HB_SubRuleSet* srs; 12935569331642446be05292e3e1f8a51218827168cdclaireho 12945569331642446be05292e3e1f8a51218827168cdclaireho 12955569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos() - 2L; 12965569331642446be05292e3e1f8a51218827168cdclaireho 12975569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 12985569331642446be05292e3e1f8a51218827168cdclaireho return error; 12995569331642446be05292e3e1f8a51218827168cdclaireho 13005569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 13015569331642446be05292e3e1f8a51218827168cdclaireho 13025569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 13035569331642446be05292e3e1f8a51218827168cdclaireho 13045569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 13055569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 13065569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &csf1->Coverage, stream ) ) != HB_Err_Ok ) 13075569331642446be05292e3e1f8a51218827168cdclaireho return error; 13085569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 13095569331642446be05292e3e1f8a51218827168cdclaireho 13105569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 13115569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 13125569331642446be05292e3e1f8a51218827168cdclaireho 13135569331642446be05292e3e1f8a51218827168cdclaireho count = csf1->SubRuleSetCount = GET_UShort(); 13145569331642446be05292e3e1f8a51218827168cdclaireho 13155569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 13165569331642446be05292e3e1f8a51218827168cdclaireho 13175569331642446be05292e3e1f8a51218827168cdclaireho csf1->SubRuleSet = NULL; 13185569331642446be05292e3e1f8a51218827168cdclaireho 13195569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( csf1->SubRuleSet, count, HB_SubRuleSet ) ) 13205569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 13215569331642446be05292e3e1f8a51218827168cdclaireho 13225569331642446be05292e3e1f8a51218827168cdclaireho srs = csf1->SubRuleSet; 13235569331642446be05292e3e1f8a51218827168cdclaireho 13245569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 13255569331642446be05292e3e1f8a51218827168cdclaireho { 13265569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 13275569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 13285569331642446be05292e3e1f8a51218827168cdclaireho 13295569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 13305569331642446be05292e3e1f8a51218827168cdclaireho 13315569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 13325569331642446be05292e3e1f8a51218827168cdclaireho 13335569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 13345569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 13355569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_SubRuleSet( &srs[n], stream ) ) != HB_Err_Ok ) 13365569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 13375569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 13385569331642446be05292e3e1f8a51218827168cdclaireho } 13395569331642446be05292e3e1f8a51218827168cdclaireho 13405569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 13415569331642446be05292e3e1f8a51218827168cdclaireho 13425569331642446be05292e3e1f8a51218827168cdclairehoFail1: 13435569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; m++ ) 13445569331642446be05292e3e1f8a51218827168cdclaireho Free_SubRuleSet( &srs[m] ); 13455569331642446be05292e3e1f8a51218827168cdclaireho 13465569331642446be05292e3e1f8a51218827168cdclaireho FREE( srs ); 13475569331642446be05292e3e1f8a51218827168cdclaireho 13485569331642446be05292e3e1f8a51218827168cdclairehoFail2: 13495569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &csf1->Coverage ); 13505569331642446be05292e3e1f8a51218827168cdclaireho return error; 13515569331642446be05292e3e1f8a51218827168cdclaireho} 13525569331642446be05292e3e1f8a51218827168cdclaireho 13535569331642446be05292e3e1f8a51218827168cdclaireho 13545569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_ContextSubst1( HB_ContextSubstFormat1* csf1 ) 13555569331642446be05292e3e1f8a51218827168cdclaireho{ 13565569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 13575569331642446be05292e3e1f8a51218827168cdclaireho 13585569331642446be05292e3e1f8a51218827168cdclaireho HB_SubRuleSet* srs; 13595569331642446be05292e3e1f8a51218827168cdclaireho 13605569331642446be05292e3e1f8a51218827168cdclaireho 13615569331642446be05292e3e1f8a51218827168cdclaireho if ( csf1->SubRuleSet ) 13625569331642446be05292e3e1f8a51218827168cdclaireho { 13635569331642446be05292e3e1f8a51218827168cdclaireho count = csf1->SubRuleSetCount; 13645569331642446be05292e3e1f8a51218827168cdclaireho srs = csf1->SubRuleSet; 13655569331642446be05292e3e1f8a51218827168cdclaireho 13665569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 13675569331642446be05292e3e1f8a51218827168cdclaireho Free_SubRuleSet( &srs[n] ); 13685569331642446be05292e3e1f8a51218827168cdclaireho 13695569331642446be05292e3e1f8a51218827168cdclaireho FREE( srs ); 13705569331642446be05292e3e1f8a51218827168cdclaireho } 13715569331642446be05292e3e1f8a51218827168cdclaireho 13725569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &csf1->Coverage ); 13735569331642446be05292e3e1f8a51218827168cdclaireho} 13745569331642446be05292e3e1f8a51218827168cdclaireho 13755569331642446be05292e3e1f8a51218827168cdclaireho 13765569331642446be05292e3e1f8a51218827168cdclaireho/* SubClassRule */ 13775569331642446be05292e3e1f8a51218827168cdclaireho 13785569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_SubClassRule( HB_ContextSubstFormat2* csf2, 13795569331642446be05292e3e1f8a51218827168cdclaireho HB_SubClassRule* scr, 13805569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 13815569331642446be05292e3e1f8a51218827168cdclaireho{ 13825569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 13835569331642446be05292e3e1f8a51218827168cdclaireho 13845569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 13855569331642446be05292e3e1f8a51218827168cdclaireho 13865569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* c; 13875569331642446be05292e3e1f8a51218827168cdclaireho HB_SubstLookupRecord* slr; 13885569331642446be05292e3e1f8a51218827168cdclaireho 13895569331642446be05292e3e1f8a51218827168cdclaireho 13905569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 4L ) ) 13915569331642446be05292e3e1f8a51218827168cdclaireho return error; 13925569331642446be05292e3e1f8a51218827168cdclaireho 13935569331642446be05292e3e1f8a51218827168cdclaireho scr->GlyphCount = GET_UShort(); 13945569331642446be05292e3e1f8a51218827168cdclaireho scr->SubstCount = GET_UShort(); 13955569331642446be05292e3e1f8a51218827168cdclaireho 13965569331642446be05292e3e1f8a51218827168cdclaireho if ( scr->GlyphCount > csf2->MaxContextLength ) 13975569331642446be05292e3e1f8a51218827168cdclaireho csf2->MaxContextLength = scr->GlyphCount; 13985569331642446be05292e3e1f8a51218827168cdclaireho 13995569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 14005569331642446be05292e3e1f8a51218827168cdclaireho 14015569331642446be05292e3e1f8a51218827168cdclaireho scr->Class = NULL; 14025569331642446be05292e3e1f8a51218827168cdclaireho 14035569331642446be05292e3e1f8a51218827168cdclaireho count = scr->GlyphCount - 1; /* only GlyphCount - 1 elements */ 14045569331642446be05292e3e1f8a51218827168cdclaireho 14055569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( scr->Class, count, HB_UShort ) ) 14065569331642446be05292e3e1f8a51218827168cdclaireho return error; 14075569331642446be05292e3e1f8a51218827168cdclaireho 14085569331642446be05292e3e1f8a51218827168cdclaireho c = scr->Class; 14095569331642446be05292e3e1f8a51218827168cdclaireho 14105569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 2L ) ) 14115569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 14125569331642446be05292e3e1f8a51218827168cdclaireho 14135569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 14145569331642446be05292e3e1f8a51218827168cdclaireho c[n] = GET_UShort(); 14155569331642446be05292e3e1f8a51218827168cdclaireho 14165569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 14175569331642446be05292e3e1f8a51218827168cdclaireho 14185569331642446be05292e3e1f8a51218827168cdclaireho scr->SubstLookupRecord = NULL; 14195569331642446be05292e3e1f8a51218827168cdclaireho 14205569331642446be05292e3e1f8a51218827168cdclaireho count = scr->SubstCount; 14215569331642446be05292e3e1f8a51218827168cdclaireho 14225569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( scr->SubstLookupRecord, count, HB_SubstLookupRecord ) ) 14235569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 14245569331642446be05292e3e1f8a51218827168cdclaireho 14255569331642446be05292e3e1f8a51218827168cdclaireho slr = scr->SubstLookupRecord; 14265569331642446be05292e3e1f8a51218827168cdclaireho 14275569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 4L ) ) 14285569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 14295569331642446be05292e3e1f8a51218827168cdclaireho 14305569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 14315569331642446be05292e3e1f8a51218827168cdclaireho { 14325569331642446be05292e3e1f8a51218827168cdclaireho slr[n].SequenceIndex = GET_UShort(); 14335569331642446be05292e3e1f8a51218827168cdclaireho slr[n].LookupListIndex = GET_UShort(); 14345569331642446be05292e3e1f8a51218827168cdclaireho } 14355569331642446be05292e3e1f8a51218827168cdclaireho 14365569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 14375569331642446be05292e3e1f8a51218827168cdclaireho 14385569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 14395569331642446be05292e3e1f8a51218827168cdclaireho 14405569331642446be05292e3e1f8a51218827168cdclairehoFail1: 14415569331642446be05292e3e1f8a51218827168cdclaireho FREE( slr ); 14425569331642446be05292e3e1f8a51218827168cdclaireho 14435569331642446be05292e3e1f8a51218827168cdclairehoFail2: 14445569331642446be05292e3e1f8a51218827168cdclaireho FREE( c ); 14455569331642446be05292e3e1f8a51218827168cdclaireho return error; 14465569331642446be05292e3e1f8a51218827168cdclaireho} 14475569331642446be05292e3e1f8a51218827168cdclaireho 14485569331642446be05292e3e1f8a51218827168cdclaireho 14495569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_SubClassRule( HB_SubClassRule* scr ) 14505569331642446be05292e3e1f8a51218827168cdclaireho{ 14515569331642446be05292e3e1f8a51218827168cdclaireho FREE( scr->SubstLookupRecord ); 14525569331642446be05292e3e1f8a51218827168cdclaireho FREE( scr->Class ); 14535569331642446be05292e3e1f8a51218827168cdclaireho} 14545569331642446be05292e3e1f8a51218827168cdclaireho 14555569331642446be05292e3e1f8a51218827168cdclaireho 14565569331642446be05292e3e1f8a51218827168cdclaireho/* SubClassSet */ 14575569331642446be05292e3e1f8a51218827168cdclaireho 14585569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_SubClassSet( HB_ContextSubstFormat2* csf2, 14595569331642446be05292e3e1f8a51218827168cdclaireho HB_SubClassSet* scs, 14605569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 14615569331642446be05292e3e1f8a51218827168cdclaireho{ 14625569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 14635569331642446be05292e3e1f8a51218827168cdclaireho 14645569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n = 0, m, count; 14655569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 14665569331642446be05292e3e1f8a51218827168cdclaireho 14675569331642446be05292e3e1f8a51218827168cdclaireho HB_SubClassRule* scr; 14685569331642446be05292e3e1f8a51218827168cdclaireho 14695569331642446be05292e3e1f8a51218827168cdclaireho 14705569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 14715569331642446be05292e3e1f8a51218827168cdclaireho 14725569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 14735569331642446be05292e3e1f8a51218827168cdclaireho return error; 14745569331642446be05292e3e1f8a51218827168cdclaireho 14755569331642446be05292e3e1f8a51218827168cdclaireho count = scs->SubClassRuleCount = GET_UShort(); 14765569331642446be05292e3e1f8a51218827168cdclaireho 14775569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 14785569331642446be05292e3e1f8a51218827168cdclaireho 14795569331642446be05292e3e1f8a51218827168cdclaireho scs->SubClassRule = NULL; 14805569331642446be05292e3e1f8a51218827168cdclaireho 14815569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( scs->SubClassRule, count, HB_SubClassRule ) ) 14825569331642446be05292e3e1f8a51218827168cdclaireho return error; 14835569331642446be05292e3e1f8a51218827168cdclaireho 14845569331642446be05292e3e1f8a51218827168cdclaireho scr = scs->SubClassRule; 14855569331642446be05292e3e1f8a51218827168cdclaireho 14865569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 14875569331642446be05292e3e1f8a51218827168cdclaireho { 14885569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 14895569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 14905569331642446be05292e3e1f8a51218827168cdclaireho 14915569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 14925569331642446be05292e3e1f8a51218827168cdclaireho 14935569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 14945569331642446be05292e3e1f8a51218827168cdclaireho 14955569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 14965569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 14975569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_SubClassRule( csf2, &scr[n], 14985569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 14995569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 15005569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 15015569331642446be05292e3e1f8a51218827168cdclaireho } 15025569331642446be05292e3e1f8a51218827168cdclaireho 15035569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 15045569331642446be05292e3e1f8a51218827168cdclaireho 15055569331642446be05292e3e1f8a51218827168cdclairehoFail: 15065569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; m++ ) 15075569331642446be05292e3e1f8a51218827168cdclaireho Free_SubClassRule( &scr[m] ); 15085569331642446be05292e3e1f8a51218827168cdclaireho 15095569331642446be05292e3e1f8a51218827168cdclaireho FREE( scr ); 15105569331642446be05292e3e1f8a51218827168cdclaireho return error; 15115569331642446be05292e3e1f8a51218827168cdclaireho} 15125569331642446be05292e3e1f8a51218827168cdclaireho 15135569331642446be05292e3e1f8a51218827168cdclaireho 15145569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_SubClassSet( HB_SubClassSet* scs ) 15155569331642446be05292e3e1f8a51218827168cdclaireho{ 15165569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 15175569331642446be05292e3e1f8a51218827168cdclaireho 15185569331642446be05292e3e1f8a51218827168cdclaireho HB_SubClassRule* scr; 15195569331642446be05292e3e1f8a51218827168cdclaireho 15205569331642446be05292e3e1f8a51218827168cdclaireho 15215569331642446be05292e3e1f8a51218827168cdclaireho if ( scs->SubClassRule ) 15225569331642446be05292e3e1f8a51218827168cdclaireho { 15235569331642446be05292e3e1f8a51218827168cdclaireho count = scs->SubClassRuleCount; 15245569331642446be05292e3e1f8a51218827168cdclaireho scr = scs->SubClassRule; 15255569331642446be05292e3e1f8a51218827168cdclaireho 15265569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 15275569331642446be05292e3e1f8a51218827168cdclaireho Free_SubClassRule( &scr[n] ); 15285569331642446be05292e3e1f8a51218827168cdclaireho 15295569331642446be05292e3e1f8a51218827168cdclaireho FREE( scr ); 15305569331642446be05292e3e1f8a51218827168cdclaireho } 15315569331642446be05292e3e1f8a51218827168cdclaireho} 15325569331642446be05292e3e1f8a51218827168cdclaireho 15335569331642446be05292e3e1f8a51218827168cdclaireho 15345569331642446be05292e3e1f8a51218827168cdclaireho/* ContextSubstFormat2 */ 15355569331642446be05292e3e1f8a51218827168cdclaireho 15365569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_ContextSubst2( HB_ContextSubstFormat2* csf2, 15375569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 15385569331642446be05292e3e1f8a51218827168cdclaireho{ 15395569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 15405569331642446be05292e3e1f8a51218827168cdclaireho 15415569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n = 0, m, count; 15425569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 15435569331642446be05292e3e1f8a51218827168cdclaireho 15445569331642446be05292e3e1f8a51218827168cdclaireho HB_SubClassSet* scs; 15455569331642446be05292e3e1f8a51218827168cdclaireho 15465569331642446be05292e3e1f8a51218827168cdclaireho 15475569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos() - 2; 15485569331642446be05292e3e1f8a51218827168cdclaireho 15495569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 15505569331642446be05292e3e1f8a51218827168cdclaireho return error; 15515569331642446be05292e3e1f8a51218827168cdclaireho 15525569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 15535569331642446be05292e3e1f8a51218827168cdclaireho 15545569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 15555569331642446be05292e3e1f8a51218827168cdclaireho 15565569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 15575569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 15585569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &csf2->Coverage, stream ) ) != HB_Err_Ok ) 15595569331642446be05292e3e1f8a51218827168cdclaireho return error; 15605569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 15615569331642446be05292e3e1f8a51218827168cdclaireho 15625569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 4L ) ) 15635569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 15645569331642446be05292e3e1f8a51218827168cdclaireho 15655569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 15665569331642446be05292e3e1f8a51218827168cdclaireho 15675569331642446be05292e3e1f8a51218827168cdclaireho /* `SubClassSetCount' is the upper limit for class values, thus we 15685569331642446be05292e3e1f8a51218827168cdclaireho read it now to make an additional safety check. */ 15695569331642446be05292e3e1f8a51218827168cdclaireho 15705569331642446be05292e3e1f8a51218827168cdclaireho count = csf2->SubClassSetCount = GET_UShort(); 15715569331642446be05292e3e1f8a51218827168cdclaireho 15725569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 15735569331642446be05292e3e1f8a51218827168cdclaireho 15745569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 15755569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 15765569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_ClassDefinition( &csf2->ClassDef, count, 15775569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 15785569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 15795569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 15805569331642446be05292e3e1f8a51218827168cdclaireho 15815569331642446be05292e3e1f8a51218827168cdclaireho csf2->SubClassSet = NULL; 15825569331642446be05292e3e1f8a51218827168cdclaireho csf2->MaxContextLength = 0; 15835569331642446be05292e3e1f8a51218827168cdclaireho 15845569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( csf2->SubClassSet, count, HB_SubClassSet ) ) 15855569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 15865569331642446be05292e3e1f8a51218827168cdclaireho 15875569331642446be05292e3e1f8a51218827168cdclaireho scs = csf2->SubClassSet; 15885569331642446be05292e3e1f8a51218827168cdclaireho 15895569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 15905569331642446be05292e3e1f8a51218827168cdclaireho { 15915569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 15925569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 15935569331642446be05292e3e1f8a51218827168cdclaireho 15945569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 15955569331642446be05292e3e1f8a51218827168cdclaireho 15965569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 15975569331642446be05292e3e1f8a51218827168cdclaireho 15985569331642446be05292e3e1f8a51218827168cdclaireho if ( new_offset != base_offset ) /* not a NULL offset */ 15995569331642446be05292e3e1f8a51218827168cdclaireho { 16005569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 16015569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 16025569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_SubClassSet( csf2, &scs[n], 16035569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 16045569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 16055569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 16065569331642446be05292e3e1f8a51218827168cdclaireho } 16075569331642446be05292e3e1f8a51218827168cdclaireho else 16085569331642446be05292e3e1f8a51218827168cdclaireho { 16095569331642446be05292e3e1f8a51218827168cdclaireho /* we create a SubClassSet table with no entries */ 16105569331642446be05292e3e1f8a51218827168cdclaireho 16115569331642446be05292e3e1f8a51218827168cdclaireho csf2->SubClassSet[n].SubClassRuleCount = 0; 16125569331642446be05292e3e1f8a51218827168cdclaireho csf2->SubClassSet[n].SubClassRule = NULL; 16135569331642446be05292e3e1f8a51218827168cdclaireho } 16145569331642446be05292e3e1f8a51218827168cdclaireho } 16155569331642446be05292e3e1f8a51218827168cdclaireho 16165569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 16175569331642446be05292e3e1f8a51218827168cdclaireho 16185569331642446be05292e3e1f8a51218827168cdclairehoFail1: 16195569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; m++ ) 16205569331642446be05292e3e1f8a51218827168cdclaireho Free_SubClassSet( &scs[m] ); 16215569331642446be05292e3e1f8a51218827168cdclaireho 16225569331642446be05292e3e1f8a51218827168cdclaireho FREE( scs ); 16235569331642446be05292e3e1f8a51218827168cdclaireho 16245569331642446be05292e3e1f8a51218827168cdclairehoFail2: 16255569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_ClassDefinition( &csf2->ClassDef ); 16265569331642446be05292e3e1f8a51218827168cdclaireho 16275569331642446be05292e3e1f8a51218827168cdclairehoFail3: 16285569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &csf2->Coverage ); 16295569331642446be05292e3e1f8a51218827168cdclaireho return error; 16305569331642446be05292e3e1f8a51218827168cdclaireho} 16315569331642446be05292e3e1f8a51218827168cdclaireho 16325569331642446be05292e3e1f8a51218827168cdclaireho 16335569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_ContextSubst2( HB_ContextSubstFormat2* csf2 ) 16345569331642446be05292e3e1f8a51218827168cdclaireho{ 16355569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 16365569331642446be05292e3e1f8a51218827168cdclaireho 16375569331642446be05292e3e1f8a51218827168cdclaireho HB_SubClassSet* scs; 16385569331642446be05292e3e1f8a51218827168cdclaireho 16395569331642446be05292e3e1f8a51218827168cdclaireho 16405569331642446be05292e3e1f8a51218827168cdclaireho if ( csf2->SubClassSet ) 16415569331642446be05292e3e1f8a51218827168cdclaireho { 16425569331642446be05292e3e1f8a51218827168cdclaireho count = csf2->SubClassSetCount; 16435569331642446be05292e3e1f8a51218827168cdclaireho scs = csf2->SubClassSet; 16445569331642446be05292e3e1f8a51218827168cdclaireho 16455569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 16465569331642446be05292e3e1f8a51218827168cdclaireho Free_SubClassSet( &scs[n] ); 16475569331642446be05292e3e1f8a51218827168cdclaireho 16485569331642446be05292e3e1f8a51218827168cdclaireho FREE( scs ); 16495569331642446be05292e3e1f8a51218827168cdclaireho } 16505569331642446be05292e3e1f8a51218827168cdclaireho 16515569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_ClassDefinition( &csf2->ClassDef ); 16525569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &csf2->Coverage ); 16535569331642446be05292e3e1f8a51218827168cdclaireho} 16545569331642446be05292e3e1f8a51218827168cdclaireho 16555569331642446be05292e3e1f8a51218827168cdclaireho 16565569331642446be05292e3e1f8a51218827168cdclaireho/* ContextSubstFormat3 */ 16575569331642446be05292e3e1f8a51218827168cdclaireho 16585569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_ContextSubst3( HB_ContextSubstFormat3* csf3, 16595569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 16605569331642446be05292e3e1f8a51218827168cdclaireho{ 16615569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 16625569331642446be05292e3e1f8a51218827168cdclaireho 16635569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n = 0, m, count; 16645569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 16655569331642446be05292e3e1f8a51218827168cdclaireho 16665569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage* c; 16675569331642446be05292e3e1f8a51218827168cdclaireho HB_SubstLookupRecord* slr; 16685569331642446be05292e3e1f8a51218827168cdclaireho 16695569331642446be05292e3e1f8a51218827168cdclaireho 16705569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos() - 2L; 16715569331642446be05292e3e1f8a51218827168cdclaireho 16725569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 4L ) ) 16735569331642446be05292e3e1f8a51218827168cdclaireho return error; 16745569331642446be05292e3e1f8a51218827168cdclaireho 16755569331642446be05292e3e1f8a51218827168cdclaireho csf3->GlyphCount = GET_UShort(); 16765569331642446be05292e3e1f8a51218827168cdclaireho csf3->SubstCount = GET_UShort(); 16775569331642446be05292e3e1f8a51218827168cdclaireho 16785569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 16795569331642446be05292e3e1f8a51218827168cdclaireho 16805569331642446be05292e3e1f8a51218827168cdclaireho csf3->Coverage = NULL; 16815569331642446be05292e3e1f8a51218827168cdclaireho 16825569331642446be05292e3e1f8a51218827168cdclaireho count = csf3->GlyphCount; 16835569331642446be05292e3e1f8a51218827168cdclaireho 16845569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( csf3->Coverage, count, HB_Coverage ) ) 16855569331642446be05292e3e1f8a51218827168cdclaireho return error; 16865569331642446be05292e3e1f8a51218827168cdclaireho 16875569331642446be05292e3e1f8a51218827168cdclaireho c = csf3->Coverage; 16885569331642446be05292e3e1f8a51218827168cdclaireho 16895569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 16905569331642446be05292e3e1f8a51218827168cdclaireho { 16915569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 16925569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 16935569331642446be05292e3e1f8a51218827168cdclaireho 16945569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 16955569331642446be05292e3e1f8a51218827168cdclaireho 16965569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 16975569331642446be05292e3e1f8a51218827168cdclaireho 16985569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 16995569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 17005569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &c[n], stream ) ) != HB_Err_Ok ) 17015569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 17025569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 17035569331642446be05292e3e1f8a51218827168cdclaireho } 17045569331642446be05292e3e1f8a51218827168cdclaireho 17055569331642446be05292e3e1f8a51218827168cdclaireho csf3->SubstLookupRecord = NULL; 17065569331642446be05292e3e1f8a51218827168cdclaireho 17075569331642446be05292e3e1f8a51218827168cdclaireho count = csf3->SubstCount; 17085569331642446be05292e3e1f8a51218827168cdclaireho 17095569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( csf3->SubstLookupRecord, count, 17105569331642446be05292e3e1f8a51218827168cdclaireho HB_SubstLookupRecord ) ) 17115569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 17125569331642446be05292e3e1f8a51218827168cdclaireho 17135569331642446be05292e3e1f8a51218827168cdclaireho slr = csf3->SubstLookupRecord; 17145569331642446be05292e3e1f8a51218827168cdclaireho 17155569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 4L ) ) 17165569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 17175569331642446be05292e3e1f8a51218827168cdclaireho 17185569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 17195569331642446be05292e3e1f8a51218827168cdclaireho { 17205569331642446be05292e3e1f8a51218827168cdclaireho slr[n].SequenceIndex = GET_UShort(); 17215569331642446be05292e3e1f8a51218827168cdclaireho slr[n].LookupListIndex = GET_UShort(); 17225569331642446be05292e3e1f8a51218827168cdclaireho } 17235569331642446be05292e3e1f8a51218827168cdclaireho 17245569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 17255569331642446be05292e3e1f8a51218827168cdclaireho 17265569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 17275569331642446be05292e3e1f8a51218827168cdclaireho 17285569331642446be05292e3e1f8a51218827168cdclairehoFail1: 17295569331642446be05292e3e1f8a51218827168cdclaireho FREE( slr ); 17305569331642446be05292e3e1f8a51218827168cdclaireho 17315569331642446be05292e3e1f8a51218827168cdclairehoFail2: 17325569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; m++ ) 17335569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &c[m] ); 17345569331642446be05292e3e1f8a51218827168cdclaireho 17355569331642446be05292e3e1f8a51218827168cdclaireho FREE( c ); 17365569331642446be05292e3e1f8a51218827168cdclaireho return error; 17375569331642446be05292e3e1f8a51218827168cdclaireho} 17385569331642446be05292e3e1f8a51218827168cdclaireho 17395569331642446be05292e3e1f8a51218827168cdclaireho 17405569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_ContextSubst3( HB_ContextSubstFormat3* csf3 ) 17415569331642446be05292e3e1f8a51218827168cdclaireho{ 17425569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 17435569331642446be05292e3e1f8a51218827168cdclaireho 17445569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage* c; 17455569331642446be05292e3e1f8a51218827168cdclaireho 17465569331642446be05292e3e1f8a51218827168cdclaireho 17475569331642446be05292e3e1f8a51218827168cdclaireho FREE( csf3->SubstLookupRecord ); 17485569331642446be05292e3e1f8a51218827168cdclaireho 17495569331642446be05292e3e1f8a51218827168cdclaireho if ( csf3->Coverage ) 17505569331642446be05292e3e1f8a51218827168cdclaireho { 17515569331642446be05292e3e1f8a51218827168cdclaireho count = csf3->GlyphCount; 17525569331642446be05292e3e1f8a51218827168cdclaireho c = csf3->Coverage; 17535569331642446be05292e3e1f8a51218827168cdclaireho 17545569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 17555569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &c[n] ); 17565569331642446be05292e3e1f8a51218827168cdclaireho 17575569331642446be05292e3e1f8a51218827168cdclaireho FREE( c ); 17585569331642446be05292e3e1f8a51218827168cdclaireho } 17595569331642446be05292e3e1f8a51218827168cdclaireho} 17605569331642446be05292e3e1f8a51218827168cdclaireho 17615569331642446be05292e3e1f8a51218827168cdclaireho 17625569331642446be05292e3e1f8a51218827168cdclaireho/* ContextSubst */ 17635569331642446be05292e3e1f8a51218827168cdclaireho 17645569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_ContextSubst( HB_GSUB_SubTable* st, 17655569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 17665569331642446be05292e3e1f8a51218827168cdclaireho{ 17675569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 17685569331642446be05292e3e1f8a51218827168cdclaireho HB_ContextSubst* cs = &st->context; 17695569331642446be05292e3e1f8a51218827168cdclaireho 17705569331642446be05292e3e1f8a51218827168cdclaireho 17715569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 17725569331642446be05292e3e1f8a51218827168cdclaireho return error; 17735569331642446be05292e3e1f8a51218827168cdclaireho 17745569331642446be05292e3e1f8a51218827168cdclaireho cs->SubstFormat = GET_UShort(); 17755569331642446be05292e3e1f8a51218827168cdclaireho 17765569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 17775569331642446be05292e3e1f8a51218827168cdclaireho 17785569331642446be05292e3e1f8a51218827168cdclaireho switch ( cs->SubstFormat ) 17795569331642446be05292e3e1f8a51218827168cdclaireho { 17805569331642446be05292e3e1f8a51218827168cdclaireho case 1: return Load_ContextSubst1( &cs->csf.csf1, stream ); 17815569331642446be05292e3e1f8a51218827168cdclaireho case 2: return Load_ContextSubst2( &cs->csf.csf2, stream ); 17825569331642446be05292e3e1f8a51218827168cdclaireho case 3: return Load_ContextSubst3( &cs->csf.csf3, stream ); 17835569331642446be05292e3e1f8a51218827168cdclaireho default: return ERR(HB_Err_Invalid_SubTable_Format); 17845569331642446be05292e3e1f8a51218827168cdclaireho } 17855569331642446be05292e3e1f8a51218827168cdclaireho 17865569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; /* never reached */ 17875569331642446be05292e3e1f8a51218827168cdclaireho} 17885569331642446be05292e3e1f8a51218827168cdclaireho 17895569331642446be05292e3e1f8a51218827168cdclaireho 17905569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_ContextSubst( HB_GSUB_SubTable* st ) 17915569331642446be05292e3e1f8a51218827168cdclaireho{ 17925569331642446be05292e3e1f8a51218827168cdclaireho HB_ContextSubst* cs = &st->context; 17935569331642446be05292e3e1f8a51218827168cdclaireho 17945569331642446be05292e3e1f8a51218827168cdclaireho switch ( cs->SubstFormat ) 17955569331642446be05292e3e1f8a51218827168cdclaireho { 17965569331642446be05292e3e1f8a51218827168cdclaireho case 1: Free_ContextSubst1( &cs->csf.csf1 ); break; 17975569331642446be05292e3e1f8a51218827168cdclaireho case 2: Free_ContextSubst2( &cs->csf.csf2 ); break; 17985569331642446be05292e3e1f8a51218827168cdclaireho case 3: Free_ContextSubst3( &cs->csf.csf3 ); break; 17995569331642446be05292e3e1f8a51218827168cdclaireho default: break; 18005569331642446be05292e3e1f8a51218827168cdclaireho } 18015569331642446be05292e3e1f8a51218827168cdclaireho} 18025569331642446be05292e3e1f8a51218827168cdclaireho 18035569331642446be05292e3e1f8a51218827168cdclaireho 18045569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Lookup_ContextSubst1( HB_GSUBHeader* gsub, 18055569331642446be05292e3e1f8a51218827168cdclaireho HB_ContextSubstFormat1* csf1, 18065569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 18075569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort flags, 18085569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 18095569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 18105569331642446be05292e3e1f8a51218827168cdclaireho{ 18115569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort index, property; 18125569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort i, j, k, numsr; 18135569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 18145569331642446be05292e3e1f8a51218827168cdclaireho 18155569331642446be05292e3e1f8a51218827168cdclaireho HB_SubRule* sr; 18165569331642446be05292e3e1f8a51218827168cdclaireho HB_GDEFHeader* gdef; 18175569331642446be05292e3e1f8a51218827168cdclaireho 18185569331642446be05292e3e1f8a51218827168cdclaireho 18195569331642446be05292e3e1f8a51218827168cdclaireho gdef = gsub->gdef; 18205569331642446be05292e3e1f8a51218827168cdclaireho 18215569331642446be05292e3e1f8a51218827168cdclaireho if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) 18225569331642446be05292e3e1f8a51218827168cdclaireho return error; 18235569331642446be05292e3e1f8a51218827168cdclaireho 18245569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &csf1->Coverage, IN_CURGLYPH(), &index ); 18255569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 18265569331642446be05292e3e1f8a51218827168cdclaireho return error; 18275569331642446be05292e3e1f8a51218827168cdclaireho 18285569331642446be05292e3e1f8a51218827168cdclaireho sr = csf1->SubRuleSet[index].SubRule; 18295569331642446be05292e3e1f8a51218827168cdclaireho numsr = csf1->SubRuleSet[index].SubRuleCount; 18305569331642446be05292e3e1f8a51218827168cdclaireho 18315569331642446be05292e3e1f8a51218827168cdclaireho for ( k = 0; k < numsr; k++ ) 18325569331642446be05292e3e1f8a51218827168cdclaireho { 18335569331642446be05292e3e1f8a51218827168cdclaireho if ( context_length != 0xFFFF && context_length < sr[k].GlyphCount ) 18345569331642446be05292e3e1f8a51218827168cdclaireho goto next_subrule; 18355569331642446be05292e3e1f8a51218827168cdclaireho 18365569331642446be05292e3e1f8a51218827168cdclaireho if ( buffer->in_pos + sr[k].GlyphCount > buffer->in_length ) 18375569331642446be05292e3e1f8a51218827168cdclaireho goto next_subrule; /* context is too long */ 18385569331642446be05292e3e1f8a51218827168cdclaireho 18395569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 1, j = buffer->in_pos + 1; i < sr[k].GlyphCount; i++, j++ ) 18405569331642446be05292e3e1f8a51218827168cdclaireho { 18415569331642446be05292e3e1f8a51218827168cdclaireho while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) 18425569331642446be05292e3e1f8a51218827168cdclaireho { 18435569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 18445569331642446be05292e3e1f8a51218827168cdclaireho return error; 18455569331642446be05292e3e1f8a51218827168cdclaireho 18465569331642446be05292e3e1f8a51218827168cdclaireho if ( j + sr[k].GlyphCount - i == (HB_Int)buffer->in_length ) 18475569331642446be05292e3e1f8a51218827168cdclaireho goto next_subrule; 18485569331642446be05292e3e1f8a51218827168cdclaireho j++; 18495569331642446be05292e3e1f8a51218827168cdclaireho } 18505569331642446be05292e3e1f8a51218827168cdclaireho 18515569331642446be05292e3e1f8a51218827168cdclaireho if ( IN_GLYPH( j ) != sr[k].Input[i - 1] ) 18525569331642446be05292e3e1f8a51218827168cdclaireho goto next_subrule; 18535569331642446be05292e3e1f8a51218827168cdclaireho } 18545569331642446be05292e3e1f8a51218827168cdclaireho 18555569331642446be05292e3e1f8a51218827168cdclaireho return Do_ContextSubst( gsub, sr[k].GlyphCount, 18565569331642446be05292e3e1f8a51218827168cdclaireho sr[k].SubstCount, sr[k].SubstLookupRecord, 18575569331642446be05292e3e1f8a51218827168cdclaireho buffer, 18585569331642446be05292e3e1f8a51218827168cdclaireho nesting_level ); 18595569331642446be05292e3e1f8a51218827168cdclaireho next_subrule: 18605569331642446be05292e3e1f8a51218827168cdclaireho ; 18615569331642446be05292e3e1f8a51218827168cdclaireho } 18625569331642446be05292e3e1f8a51218827168cdclaireho 18635569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 18645569331642446be05292e3e1f8a51218827168cdclaireho} 18655569331642446be05292e3e1f8a51218827168cdclaireho 18665569331642446be05292e3e1f8a51218827168cdclaireho 18675569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Lookup_ContextSubst2( HB_GSUBHeader* gsub, 18685569331642446be05292e3e1f8a51218827168cdclaireho HB_ContextSubstFormat2* csf2, 18695569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 18705569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort flags, 18715569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 18725569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 18735569331642446be05292e3e1f8a51218827168cdclaireho{ 18745569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort index, property; 18755569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 18765569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort i, j, k, known_classes; 18775569331642446be05292e3e1f8a51218827168cdclaireho 18785569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* classes; 18795569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* cl; 18805569331642446be05292e3e1f8a51218827168cdclaireho 18815569331642446be05292e3e1f8a51218827168cdclaireho HB_SubClassSet* scs; 18825569331642446be05292e3e1f8a51218827168cdclaireho HB_SubClassRule* sr; 18835569331642446be05292e3e1f8a51218827168cdclaireho HB_GDEFHeader* gdef; 18845569331642446be05292e3e1f8a51218827168cdclaireho 18855569331642446be05292e3e1f8a51218827168cdclaireho 18865569331642446be05292e3e1f8a51218827168cdclaireho gdef = gsub->gdef; 18875569331642446be05292e3e1f8a51218827168cdclaireho 18885569331642446be05292e3e1f8a51218827168cdclaireho if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) 18895569331642446be05292e3e1f8a51218827168cdclaireho return error; 18905569331642446be05292e3e1f8a51218827168cdclaireho 18915569331642446be05292e3e1f8a51218827168cdclaireho /* Note: The coverage table in format 2 doesn't give an index into 18925569331642446be05292e3e1f8a51218827168cdclaireho anything. It just lets us know whether or not we need to 18935569331642446be05292e3e1f8a51218827168cdclaireho do any lookup at all. */ 18945569331642446be05292e3e1f8a51218827168cdclaireho 18955569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &csf2->Coverage, IN_CURGLYPH(), &index ); 18965569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 18975569331642446be05292e3e1f8a51218827168cdclaireho return error; 18985569331642446be05292e3e1f8a51218827168cdclaireho 18995569331642446be05292e3e1f8a51218827168cdclaireho if (csf2->MaxContextLength < 1) 19005569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 19015569331642446be05292e3e1f8a51218827168cdclaireho 19025569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( classes, csf2->MaxContextLength, HB_UShort ) ) 19035569331642446be05292e3e1f8a51218827168cdclaireho return error; 19045569331642446be05292e3e1f8a51218827168cdclaireho 19055569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Get_Class( &csf2->ClassDef, IN_CURGLYPH(), 19065569331642446be05292e3e1f8a51218827168cdclaireho &classes[0], NULL ); 19075569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 19085569331642446be05292e3e1f8a51218827168cdclaireho goto End; 19095569331642446be05292e3e1f8a51218827168cdclaireho known_classes = 0; 19105569331642446be05292e3e1f8a51218827168cdclaireho 19115569331642446be05292e3e1f8a51218827168cdclaireho scs = &csf2->SubClassSet[classes[0]]; 19125569331642446be05292e3e1f8a51218827168cdclaireho if ( !scs ) 19135569331642446be05292e3e1f8a51218827168cdclaireho { 19145569331642446be05292e3e1f8a51218827168cdclaireho error = ERR(HB_Err_Invalid_SubTable); 19155569331642446be05292e3e1f8a51218827168cdclaireho goto End; 19165569331642446be05292e3e1f8a51218827168cdclaireho } 19175569331642446be05292e3e1f8a51218827168cdclaireho 19185569331642446be05292e3e1f8a51218827168cdclaireho for ( k = 0; k < scs->SubClassRuleCount; k++ ) 19195569331642446be05292e3e1f8a51218827168cdclaireho { 19205569331642446be05292e3e1f8a51218827168cdclaireho sr = &scs->SubClassRule[k]; 19215569331642446be05292e3e1f8a51218827168cdclaireho 19225569331642446be05292e3e1f8a51218827168cdclaireho if ( context_length != 0xFFFF && context_length < sr->GlyphCount ) 19235569331642446be05292e3e1f8a51218827168cdclaireho goto next_subclassrule; 19245569331642446be05292e3e1f8a51218827168cdclaireho 19255569331642446be05292e3e1f8a51218827168cdclaireho if ( buffer->in_pos + sr->GlyphCount > buffer->in_length ) 19265569331642446be05292e3e1f8a51218827168cdclaireho goto next_subclassrule; /* context is too long */ 19275569331642446be05292e3e1f8a51218827168cdclaireho 19285569331642446be05292e3e1f8a51218827168cdclaireho cl = sr->Class; 19295569331642446be05292e3e1f8a51218827168cdclaireho 19305569331642446be05292e3e1f8a51218827168cdclaireho /* Start at 1 because [0] is implied */ 19315569331642446be05292e3e1f8a51218827168cdclaireho 19325569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 1, j = buffer->in_pos + 1; i < sr->GlyphCount; i++, j++ ) 19335569331642446be05292e3e1f8a51218827168cdclaireho { 19345569331642446be05292e3e1f8a51218827168cdclaireho while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) 19355569331642446be05292e3e1f8a51218827168cdclaireho { 19365569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 19375569331642446be05292e3e1f8a51218827168cdclaireho goto End; 19385569331642446be05292e3e1f8a51218827168cdclaireho 19395569331642446be05292e3e1f8a51218827168cdclaireho if ( j + sr->GlyphCount - i < (HB_Int)buffer->in_length ) 19405569331642446be05292e3e1f8a51218827168cdclaireho goto next_subclassrule; 19415569331642446be05292e3e1f8a51218827168cdclaireho j++; 19425569331642446be05292e3e1f8a51218827168cdclaireho } 19435569331642446be05292e3e1f8a51218827168cdclaireho 19445569331642446be05292e3e1f8a51218827168cdclaireho if ( i > known_classes ) 19455569331642446be05292e3e1f8a51218827168cdclaireho { 19465569331642446be05292e3e1f8a51218827168cdclaireho /* Keeps us from having to do this for each rule */ 19475569331642446be05292e3e1f8a51218827168cdclaireho 19485569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Get_Class( &csf2->ClassDef, IN_GLYPH( j ), &classes[i], NULL ); 19495569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 19505569331642446be05292e3e1f8a51218827168cdclaireho goto End; 19515569331642446be05292e3e1f8a51218827168cdclaireho known_classes = i; 19525569331642446be05292e3e1f8a51218827168cdclaireho } 19535569331642446be05292e3e1f8a51218827168cdclaireho 19545569331642446be05292e3e1f8a51218827168cdclaireho if ( cl[i - 1] != classes[i] ) 19555569331642446be05292e3e1f8a51218827168cdclaireho goto next_subclassrule; 19565569331642446be05292e3e1f8a51218827168cdclaireho } 19575569331642446be05292e3e1f8a51218827168cdclaireho 19585569331642446be05292e3e1f8a51218827168cdclaireho error = Do_ContextSubst( gsub, sr->GlyphCount, 19595569331642446be05292e3e1f8a51218827168cdclaireho sr->SubstCount, sr->SubstLookupRecord, 19605569331642446be05292e3e1f8a51218827168cdclaireho buffer, 19615569331642446be05292e3e1f8a51218827168cdclaireho nesting_level ); 19625569331642446be05292e3e1f8a51218827168cdclaireho goto End; 19635569331642446be05292e3e1f8a51218827168cdclaireho 19645569331642446be05292e3e1f8a51218827168cdclaireho next_subclassrule: 19655569331642446be05292e3e1f8a51218827168cdclaireho ; 19665569331642446be05292e3e1f8a51218827168cdclaireho } 19675569331642446be05292e3e1f8a51218827168cdclaireho 19685569331642446be05292e3e1f8a51218827168cdclaireho error = HB_Err_Not_Covered; 19695569331642446be05292e3e1f8a51218827168cdclaireho 19705569331642446be05292e3e1f8a51218827168cdclairehoEnd: 19715569331642446be05292e3e1f8a51218827168cdclaireho FREE( classes ); 19725569331642446be05292e3e1f8a51218827168cdclaireho return error; 19735569331642446be05292e3e1f8a51218827168cdclaireho} 19745569331642446be05292e3e1f8a51218827168cdclaireho 19755569331642446be05292e3e1f8a51218827168cdclaireho 19765569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Lookup_ContextSubst3( HB_GSUBHeader* gsub, 19775569331642446be05292e3e1f8a51218827168cdclaireho HB_ContextSubstFormat3* csf3, 19785569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 19795569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort flags, 19805569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 19815569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 19825569331642446be05292e3e1f8a51218827168cdclaireho{ 19835569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 19845569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort index, i, j, property; 19855569331642446be05292e3e1f8a51218827168cdclaireho 19865569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage* c; 19875569331642446be05292e3e1f8a51218827168cdclaireho HB_GDEFHeader* gdef; 19885569331642446be05292e3e1f8a51218827168cdclaireho 19895569331642446be05292e3e1f8a51218827168cdclaireho 19905569331642446be05292e3e1f8a51218827168cdclaireho gdef = gsub->gdef; 19915569331642446be05292e3e1f8a51218827168cdclaireho 19925569331642446be05292e3e1f8a51218827168cdclaireho if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) 19935569331642446be05292e3e1f8a51218827168cdclaireho return error; 19945569331642446be05292e3e1f8a51218827168cdclaireho 19955569331642446be05292e3e1f8a51218827168cdclaireho if ( context_length != 0xFFFF && context_length < csf3->GlyphCount ) 19965569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 19975569331642446be05292e3e1f8a51218827168cdclaireho 19985569331642446be05292e3e1f8a51218827168cdclaireho if ( buffer->in_pos + csf3->GlyphCount > buffer->in_length ) 19995569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; /* context is too long */ 20005569331642446be05292e3e1f8a51218827168cdclaireho 20015569331642446be05292e3e1f8a51218827168cdclaireho c = csf3->Coverage; 20025569331642446be05292e3e1f8a51218827168cdclaireho 20035569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 1, j = buffer->in_pos + 1; i < csf3->GlyphCount; i++, j++ ) 20045569331642446be05292e3e1f8a51218827168cdclaireho { 20055569331642446be05292e3e1f8a51218827168cdclaireho while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) 20065569331642446be05292e3e1f8a51218827168cdclaireho { 20075569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 20085569331642446be05292e3e1f8a51218827168cdclaireho return error; 20095569331642446be05292e3e1f8a51218827168cdclaireho 20105569331642446be05292e3e1f8a51218827168cdclaireho if ( j + csf3->GlyphCount - i == (HB_Int)buffer->in_length ) 20115569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 20125569331642446be05292e3e1f8a51218827168cdclaireho j++; 20135569331642446be05292e3e1f8a51218827168cdclaireho } 20145569331642446be05292e3e1f8a51218827168cdclaireho 20155569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &c[i], IN_GLYPH( j ), &index ); 20165569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 20175569331642446be05292e3e1f8a51218827168cdclaireho return error; 20185569331642446be05292e3e1f8a51218827168cdclaireho } 20195569331642446be05292e3e1f8a51218827168cdclaireho 20205569331642446be05292e3e1f8a51218827168cdclaireho return Do_ContextSubst( gsub, csf3->GlyphCount, 20215569331642446be05292e3e1f8a51218827168cdclaireho csf3->SubstCount, csf3->SubstLookupRecord, 20225569331642446be05292e3e1f8a51218827168cdclaireho buffer, 20235569331642446be05292e3e1f8a51218827168cdclaireho nesting_level ); 20245569331642446be05292e3e1f8a51218827168cdclaireho} 20255569331642446be05292e3e1f8a51218827168cdclaireho 20265569331642446be05292e3e1f8a51218827168cdclaireho 20275569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Lookup_ContextSubst( HB_GSUBHeader* gsub, 20285569331642446be05292e3e1f8a51218827168cdclaireho HB_GSUB_SubTable* st, 20295569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 20305569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort flags, 20315569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 20325569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 20335569331642446be05292e3e1f8a51218827168cdclaireho{ 20345569331642446be05292e3e1f8a51218827168cdclaireho HB_ContextSubst* cs = &st->context; 20355569331642446be05292e3e1f8a51218827168cdclaireho 20365569331642446be05292e3e1f8a51218827168cdclaireho switch ( cs->SubstFormat ) 20375569331642446be05292e3e1f8a51218827168cdclaireho { 20385569331642446be05292e3e1f8a51218827168cdclaireho case 1: return Lookup_ContextSubst1( gsub, &cs->csf.csf1, buffer, flags, context_length, nesting_level ); 20395569331642446be05292e3e1f8a51218827168cdclaireho case 2: return Lookup_ContextSubst2( gsub, &cs->csf.csf2, buffer, flags, context_length, nesting_level ); 20405569331642446be05292e3e1f8a51218827168cdclaireho case 3: return Lookup_ContextSubst3( gsub, &cs->csf.csf3, buffer, flags, context_length, nesting_level ); 20415569331642446be05292e3e1f8a51218827168cdclaireho default: return ERR(HB_Err_Invalid_SubTable_Format); 20425569331642446be05292e3e1f8a51218827168cdclaireho } 20435569331642446be05292e3e1f8a51218827168cdclaireho 20445569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; /* never reached */ 20455569331642446be05292e3e1f8a51218827168cdclaireho} 20465569331642446be05292e3e1f8a51218827168cdclaireho 20475569331642446be05292e3e1f8a51218827168cdclaireho 20485569331642446be05292e3e1f8a51218827168cdclaireho/* LookupType 6 */ 20495569331642446be05292e3e1f8a51218827168cdclaireho 20505569331642446be05292e3e1f8a51218827168cdclaireho/* ChainSubRule */ 20515569331642446be05292e3e1f8a51218827168cdclaireho 20525569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_ChainSubRule( HB_ChainSubRule* csr, 20535569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 20545569331642446be05292e3e1f8a51218827168cdclaireho{ 20555569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 20565569331642446be05292e3e1f8a51218827168cdclaireho 20575569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 20585569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* b; 20595569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* i; 20605569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* l; 20615569331642446be05292e3e1f8a51218827168cdclaireho 20625569331642446be05292e3e1f8a51218827168cdclaireho HB_SubstLookupRecord* slr; 20635569331642446be05292e3e1f8a51218827168cdclaireho 20645569331642446be05292e3e1f8a51218827168cdclaireho 20655569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 20665569331642446be05292e3e1f8a51218827168cdclaireho return error; 20675569331642446be05292e3e1f8a51218827168cdclaireho 20685569331642446be05292e3e1f8a51218827168cdclaireho csr->BacktrackGlyphCount = GET_UShort(); 20695569331642446be05292e3e1f8a51218827168cdclaireho 20705569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 20715569331642446be05292e3e1f8a51218827168cdclaireho 20725569331642446be05292e3e1f8a51218827168cdclaireho csr->Backtrack = NULL; 20735569331642446be05292e3e1f8a51218827168cdclaireho 20745569331642446be05292e3e1f8a51218827168cdclaireho count = csr->BacktrackGlyphCount; 20755569331642446be05292e3e1f8a51218827168cdclaireho 20765569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( csr->Backtrack, count, HB_UShort ) ) 20775569331642446be05292e3e1f8a51218827168cdclaireho return error; 20785569331642446be05292e3e1f8a51218827168cdclaireho 20795569331642446be05292e3e1f8a51218827168cdclaireho b = csr->Backtrack; 20805569331642446be05292e3e1f8a51218827168cdclaireho 20815569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 2L ) ) 20825569331642446be05292e3e1f8a51218827168cdclaireho goto Fail4; 20835569331642446be05292e3e1f8a51218827168cdclaireho 20845569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 20855569331642446be05292e3e1f8a51218827168cdclaireho b[n] = GET_UShort(); 20865569331642446be05292e3e1f8a51218827168cdclaireho 20875569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 20885569331642446be05292e3e1f8a51218827168cdclaireho 20895569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 20905569331642446be05292e3e1f8a51218827168cdclaireho goto Fail4; 20915569331642446be05292e3e1f8a51218827168cdclaireho 20925569331642446be05292e3e1f8a51218827168cdclaireho csr->InputGlyphCount = GET_UShort(); 20935569331642446be05292e3e1f8a51218827168cdclaireho 20945569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 20955569331642446be05292e3e1f8a51218827168cdclaireho 20965569331642446be05292e3e1f8a51218827168cdclaireho csr->Input = NULL; 20975569331642446be05292e3e1f8a51218827168cdclaireho 20985569331642446be05292e3e1f8a51218827168cdclaireho count = csr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */ 20995569331642446be05292e3e1f8a51218827168cdclaireho 21005569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( csr->Input, count, HB_UShort ) ) 21015569331642446be05292e3e1f8a51218827168cdclaireho goto Fail4; 21025569331642446be05292e3e1f8a51218827168cdclaireho 21035569331642446be05292e3e1f8a51218827168cdclaireho i = csr->Input; 21045569331642446be05292e3e1f8a51218827168cdclaireho 21055569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 2L ) ) 21065569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 21075569331642446be05292e3e1f8a51218827168cdclaireho 21085569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 21095569331642446be05292e3e1f8a51218827168cdclaireho i[n] = GET_UShort(); 21105569331642446be05292e3e1f8a51218827168cdclaireho 21115569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 21125569331642446be05292e3e1f8a51218827168cdclaireho 21135569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 21145569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 21155569331642446be05292e3e1f8a51218827168cdclaireho 21165569331642446be05292e3e1f8a51218827168cdclaireho csr->LookaheadGlyphCount = GET_UShort(); 21175569331642446be05292e3e1f8a51218827168cdclaireho 21185569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 21195569331642446be05292e3e1f8a51218827168cdclaireho 21205569331642446be05292e3e1f8a51218827168cdclaireho csr->Lookahead = NULL; 21215569331642446be05292e3e1f8a51218827168cdclaireho 21225569331642446be05292e3e1f8a51218827168cdclaireho count = csr->LookaheadGlyphCount; 21235569331642446be05292e3e1f8a51218827168cdclaireho 21245569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( csr->Lookahead, count, HB_UShort ) ) 21255569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 21265569331642446be05292e3e1f8a51218827168cdclaireho 21275569331642446be05292e3e1f8a51218827168cdclaireho l = csr->Lookahead; 21285569331642446be05292e3e1f8a51218827168cdclaireho 21295569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 2L ) ) 21305569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 21315569331642446be05292e3e1f8a51218827168cdclaireho 21325569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 21335569331642446be05292e3e1f8a51218827168cdclaireho l[n] = GET_UShort(); 21345569331642446be05292e3e1f8a51218827168cdclaireho 21355569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 21365569331642446be05292e3e1f8a51218827168cdclaireho 21375569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 21385569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 21395569331642446be05292e3e1f8a51218827168cdclaireho 21405569331642446be05292e3e1f8a51218827168cdclaireho csr->SubstCount = GET_UShort(); 21415569331642446be05292e3e1f8a51218827168cdclaireho 21425569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 21435569331642446be05292e3e1f8a51218827168cdclaireho 21445569331642446be05292e3e1f8a51218827168cdclaireho csr->SubstLookupRecord = NULL; 21455569331642446be05292e3e1f8a51218827168cdclaireho 21465569331642446be05292e3e1f8a51218827168cdclaireho count = csr->SubstCount; 21475569331642446be05292e3e1f8a51218827168cdclaireho 21485569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( csr->SubstLookupRecord, count, HB_SubstLookupRecord ) ) 21495569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 21505569331642446be05292e3e1f8a51218827168cdclaireho 21515569331642446be05292e3e1f8a51218827168cdclaireho slr = csr->SubstLookupRecord; 21525569331642446be05292e3e1f8a51218827168cdclaireho 21535569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 4L ) ) 21545569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 21555569331642446be05292e3e1f8a51218827168cdclaireho 21565569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 21575569331642446be05292e3e1f8a51218827168cdclaireho { 21585569331642446be05292e3e1f8a51218827168cdclaireho slr[n].SequenceIndex = GET_UShort(); 21595569331642446be05292e3e1f8a51218827168cdclaireho slr[n].LookupListIndex = GET_UShort(); 21605569331642446be05292e3e1f8a51218827168cdclaireho } 21615569331642446be05292e3e1f8a51218827168cdclaireho 21625569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 21635569331642446be05292e3e1f8a51218827168cdclaireho 21645569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 21655569331642446be05292e3e1f8a51218827168cdclaireho 21665569331642446be05292e3e1f8a51218827168cdclairehoFail1: 21675569331642446be05292e3e1f8a51218827168cdclaireho FREE( slr ); 21685569331642446be05292e3e1f8a51218827168cdclaireho 21695569331642446be05292e3e1f8a51218827168cdclairehoFail2: 21705569331642446be05292e3e1f8a51218827168cdclaireho FREE( l ); 21715569331642446be05292e3e1f8a51218827168cdclaireho 21725569331642446be05292e3e1f8a51218827168cdclairehoFail3: 21735569331642446be05292e3e1f8a51218827168cdclaireho FREE( i ); 21745569331642446be05292e3e1f8a51218827168cdclaireho 21755569331642446be05292e3e1f8a51218827168cdclairehoFail4: 21765569331642446be05292e3e1f8a51218827168cdclaireho FREE( b ); 21775569331642446be05292e3e1f8a51218827168cdclaireho return error; 21785569331642446be05292e3e1f8a51218827168cdclaireho} 21795569331642446be05292e3e1f8a51218827168cdclaireho 21805569331642446be05292e3e1f8a51218827168cdclaireho 21815569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_ChainSubRule( HB_ChainSubRule* csr ) 21825569331642446be05292e3e1f8a51218827168cdclaireho{ 21835569331642446be05292e3e1f8a51218827168cdclaireho FREE( csr->SubstLookupRecord ); 21845569331642446be05292e3e1f8a51218827168cdclaireho FREE( csr->Lookahead ); 21855569331642446be05292e3e1f8a51218827168cdclaireho FREE( csr->Input ); 21865569331642446be05292e3e1f8a51218827168cdclaireho FREE( csr->Backtrack ); 21875569331642446be05292e3e1f8a51218827168cdclaireho} 21885569331642446be05292e3e1f8a51218827168cdclaireho 21895569331642446be05292e3e1f8a51218827168cdclaireho 21905569331642446be05292e3e1f8a51218827168cdclaireho/* ChainSubRuleSet */ 21915569331642446be05292e3e1f8a51218827168cdclaireho 21925569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_ChainSubRuleSet( HB_ChainSubRuleSet* csrs, 21935569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 21945569331642446be05292e3e1f8a51218827168cdclaireho{ 21955569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 21965569331642446be05292e3e1f8a51218827168cdclaireho 21975569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n = 0, m, count; 21985569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 21995569331642446be05292e3e1f8a51218827168cdclaireho 22005569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainSubRule* csr; 22015569331642446be05292e3e1f8a51218827168cdclaireho 22025569331642446be05292e3e1f8a51218827168cdclaireho 22035569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 22045569331642446be05292e3e1f8a51218827168cdclaireho 22055569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 22065569331642446be05292e3e1f8a51218827168cdclaireho return error; 22075569331642446be05292e3e1f8a51218827168cdclaireho 22085569331642446be05292e3e1f8a51218827168cdclaireho count = csrs->ChainSubRuleCount = GET_UShort(); 22095569331642446be05292e3e1f8a51218827168cdclaireho 22105569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 22115569331642446be05292e3e1f8a51218827168cdclaireho 22125569331642446be05292e3e1f8a51218827168cdclaireho csrs->ChainSubRule = NULL; 22135569331642446be05292e3e1f8a51218827168cdclaireho 22145569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( csrs->ChainSubRule, count, HB_ChainSubRule ) ) 22155569331642446be05292e3e1f8a51218827168cdclaireho return error; 22165569331642446be05292e3e1f8a51218827168cdclaireho 22175569331642446be05292e3e1f8a51218827168cdclaireho csr = csrs->ChainSubRule; 22185569331642446be05292e3e1f8a51218827168cdclaireho 22195569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 22205569331642446be05292e3e1f8a51218827168cdclaireho { 22215569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 22225569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 22235569331642446be05292e3e1f8a51218827168cdclaireho 22245569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 22255569331642446be05292e3e1f8a51218827168cdclaireho 22265569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 22275569331642446be05292e3e1f8a51218827168cdclaireho 22285569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 22295569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 22305569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_ChainSubRule( &csr[n], stream ) ) != HB_Err_Ok ) 22315569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 22325569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 22335569331642446be05292e3e1f8a51218827168cdclaireho } 22345569331642446be05292e3e1f8a51218827168cdclaireho 22355569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 22365569331642446be05292e3e1f8a51218827168cdclaireho 22375569331642446be05292e3e1f8a51218827168cdclairehoFail: 22385569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; m++ ) 22395569331642446be05292e3e1f8a51218827168cdclaireho Free_ChainSubRule( &csr[m] ); 22405569331642446be05292e3e1f8a51218827168cdclaireho 22415569331642446be05292e3e1f8a51218827168cdclaireho FREE( csr ); 22425569331642446be05292e3e1f8a51218827168cdclaireho return error; 22435569331642446be05292e3e1f8a51218827168cdclaireho} 22445569331642446be05292e3e1f8a51218827168cdclaireho 22455569331642446be05292e3e1f8a51218827168cdclaireho 22465569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_ChainSubRuleSet( HB_ChainSubRuleSet* csrs ) 22475569331642446be05292e3e1f8a51218827168cdclaireho{ 22485569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 22495569331642446be05292e3e1f8a51218827168cdclaireho 22505569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainSubRule* csr; 22515569331642446be05292e3e1f8a51218827168cdclaireho 22525569331642446be05292e3e1f8a51218827168cdclaireho 22535569331642446be05292e3e1f8a51218827168cdclaireho if ( csrs->ChainSubRule ) 22545569331642446be05292e3e1f8a51218827168cdclaireho { 22555569331642446be05292e3e1f8a51218827168cdclaireho count = csrs->ChainSubRuleCount; 22565569331642446be05292e3e1f8a51218827168cdclaireho csr = csrs->ChainSubRule; 22575569331642446be05292e3e1f8a51218827168cdclaireho 22585569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 22595569331642446be05292e3e1f8a51218827168cdclaireho Free_ChainSubRule( &csr[n] ); 22605569331642446be05292e3e1f8a51218827168cdclaireho 22615569331642446be05292e3e1f8a51218827168cdclaireho FREE( csr ); 22625569331642446be05292e3e1f8a51218827168cdclaireho } 22635569331642446be05292e3e1f8a51218827168cdclaireho} 22645569331642446be05292e3e1f8a51218827168cdclaireho 22655569331642446be05292e3e1f8a51218827168cdclaireho 22665569331642446be05292e3e1f8a51218827168cdclaireho/* ChainContextSubstFormat1 */ 22675569331642446be05292e3e1f8a51218827168cdclaireho 22685569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_ChainContextSubst1( 22695569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainContextSubstFormat1* ccsf1, 22705569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 22715569331642446be05292e3e1f8a51218827168cdclaireho{ 22725569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 22735569331642446be05292e3e1f8a51218827168cdclaireho 22745569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n = 0, m, count; 22755569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 22765569331642446be05292e3e1f8a51218827168cdclaireho 22775569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainSubRuleSet* csrs; 22785569331642446be05292e3e1f8a51218827168cdclaireho 22795569331642446be05292e3e1f8a51218827168cdclaireho 22805569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos() - 2L; 22815569331642446be05292e3e1f8a51218827168cdclaireho 22825569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 22835569331642446be05292e3e1f8a51218827168cdclaireho return error; 22845569331642446be05292e3e1f8a51218827168cdclaireho 22855569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 22865569331642446be05292e3e1f8a51218827168cdclaireho 22875569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 22885569331642446be05292e3e1f8a51218827168cdclaireho 22895569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 22905569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 22915569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &ccsf1->Coverage, stream ) ) != HB_Err_Ok ) 22925569331642446be05292e3e1f8a51218827168cdclaireho return error; 22935569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 22945569331642446be05292e3e1f8a51218827168cdclaireho 22955569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 22965569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 22975569331642446be05292e3e1f8a51218827168cdclaireho 22985569331642446be05292e3e1f8a51218827168cdclaireho count = ccsf1->ChainSubRuleSetCount = GET_UShort(); 22995569331642446be05292e3e1f8a51218827168cdclaireho 23005569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 23015569331642446be05292e3e1f8a51218827168cdclaireho 23025569331642446be05292e3e1f8a51218827168cdclaireho ccsf1->ChainSubRuleSet = NULL; 23035569331642446be05292e3e1f8a51218827168cdclaireho 23045569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( ccsf1->ChainSubRuleSet, count, HB_ChainSubRuleSet ) ) 23055569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 23065569331642446be05292e3e1f8a51218827168cdclaireho 23075569331642446be05292e3e1f8a51218827168cdclaireho csrs = ccsf1->ChainSubRuleSet; 23085569331642446be05292e3e1f8a51218827168cdclaireho 23095569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 23105569331642446be05292e3e1f8a51218827168cdclaireho { 23115569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 23125569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 23135569331642446be05292e3e1f8a51218827168cdclaireho 23145569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 23155569331642446be05292e3e1f8a51218827168cdclaireho 23165569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 23175569331642446be05292e3e1f8a51218827168cdclaireho 23185569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 23195569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 23205569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_ChainSubRuleSet( &csrs[n], stream ) ) != HB_Err_Ok ) 23215569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 23225569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 23235569331642446be05292e3e1f8a51218827168cdclaireho } 23245569331642446be05292e3e1f8a51218827168cdclaireho 23255569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 23265569331642446be05292e3e1f8a51218827168cdclaireho 23275569331642446be05292e3e1f8a51218827168cdclairehoFail1: 23285569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; m++ ) 23295569331642446be05292e3e1f8a51218827168cdclaireho Free_ChainSubRuleSet( &csrs[m] ); 23305569331642446be05292e3e1f8a51218827168cdclaireho 23315569331642446be05292e3e1f8a51218827168cdclaireho FREE( csrs ); 23325569331642446be05292e3e1f8a51218827168cdclaireho 23335569331642446be05292e3e1f8a51218827168cdclairehoFail2: 23345569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &ccsf1->Coverage ); 23355569331642446be05292e3e1f8a51218827168cdclaireho return error; 23365569331642446be05292e3e1f8a51218827168cdclaireho} 23375569331642446be05292e3e1f8a51218827168cdclaireho 23385569331642446be05292e3e1f8a51218827168cdclaireho 23395569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_ChainContextSubst1( HB_ChainContextSubstFormat1* ccsf1 ) 23405569331642446be05292e3e1f8a51218827168cdclaireho{ 23415569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 23425569331642446be05292e3e1f8a51218827168cdclaireho 23435569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainSubRuleSet* csrs; 23445569331642446be05292e3e1f8a51218827168cdclaireho 23455569331642446be05292e3e1f8a51218827168cdclaireho 23465569331642446be05292e3e1f8a51218827168cdclaireho if ( ccsf1->ChainSubRuleSet ) 23475569331642446be05292e3e1f8a51218827168cdclaireho { 23485569331642446be05292e3e1f8a51218827168cdclaireho count = ccsf1->ChainSubRuleSetCount; 23495569331642446be05292e3e1f8a51218827168cdclaireho csrs = ccsf1->ChainSubRuleSet; 23505569331642446be05292e3e1f8a51218827168cdclaireho 23515569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 23525569331642446be05292e3e1f8a51218827168cdclaireho Free_ChainSubRuleSet( &csrs[n] ); 23535569331642446be05292e3e1f8a51218827168cdclaireho 23545569331642446be05292e3e1f8a51218827168cdclaireho FREE( csrs ); 23555569331642446be05292e3e1f8a51218827168cdclaireho } 23565569331642446be05292e3e1f8a51218827168cdclaireho 23575569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &ccsf1->Coverage ); 23585569331642446be05292e3e1f8a51218827168cdclaireho} 23595569331642446be05292e3e1f8a51218827168cdclaireho 23605569331642446be05292e3e1f8a51218827168cdclaireho 23615569331642446be05292e3e1f8a51218827168cdclaireho/* ChainSubClassRule */ 23625569331642446be05292e3e1f8a51218827168cdclaireho 23635569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_ChainSubClassRule( 23645569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainContextSubstFormat2* ccsf2, 23655569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainSubClassRule* cscr, 23665569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 23675569331642446be05292e3e1f8a51218827168cdclaireho{ 23685569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 23695569331642446be05292e3e1f8a51218827168cdclaireho 23705569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 23715569331642446be05292e3e1f8a51218827168cdclaireho 23725569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* b; 23735569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* i; 23745569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* l; 23755569331642446be05292e3e1f8a51218827168cdclaireho HB_SubstLookupRecord* slr; 23765569331642446be05292e3e1f8a51218827168cdclaireho 23775569331642446be05292e3e1f8a51218827168cdclaireho 23785569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 23795569331642446be05292e3e1f8a51218827168cdclaireho return error; 23805569331642446be05292e3e1f8a51218827168cdclaireho 23815569331642446be05292e3e1f8a51218827168cdclaireho cscr->BacktrackGlyphCount = GET_UShort(); 23825569331642446be05292e3e1f8a51218827168cdclaireho 23835569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 23845569331642446be05292e3e1f8a51218827168cdclaireho 23855569331642446be05292e3e1f8a51218827168cdclaireho if ( cscr->BacktrackGlyphCount > ccsf2->MaxBacktrackLength ) 23865569331642446be05292e3e1f8a51218827168cdclaireho ccsf2->MaxBacktrackLength = cscr->BacktrackGlyphCount; 23875569331642446be05292e3e1f8a51218827168cdclaireho 23885569331642446be05292e3e1f8a51218827168cdclaireho cscr->Backtrack = NULL; 23895569331642446be05292e3e1f8a51218827168cdclaireho 23905569331642446be05292e3e1f8a51218827168cdclaireho count = cscr->BacktrackGlyphCount; 23915569331642446be05292e3e1f8a51218827168cdclaireho 23925569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( cscr->Backtrack, count, HB_UShort ) ) 23935569331642446be05292e3e1f8a51218827168cdclaireho return error; 23945569331642446be05292e3e1f8a51218827168cdclaireho 23955569331642446be05292e3e1f8a51218827168cdclaireho b = cscr->Backtrack; 23965569331642446be05292e3e1f8a51218827168cdclaireho 23975569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 2L ) ) 23985569331642446be05292e3e1f8a51218827168cdclaireho goto Fail4; 23995569331642446be05292e3e1f8a51218827168cdclaireho 24005569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 24015569331642446be05292e3e1f8a51218827168cdclaireho b[n] = GET_UShort(); 24025569331642446be05292e3e1f8a51218827168cdclaireho 24035569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 24045569331642446be05292e3e1f8a51218827168cdclaireho 24055569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 24065569331642446be05292e3e1f8a51218827168cdclaireho goto Fail4; 24075569331642446be05292e3e1f8a51218827168cdclaireho 24085569331642446be05292e3e1f8a51218827168cdclaireho cscr->InputGlyphCount = GET_UShort(); 24095569331642446be05292e3e1f8a51218827168cdclaireho 24105569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 24115569331642446be05292e3e1f8a51218827168cdclaireho 24125569331642446be05292e3e1f8a51218827168cdclaireho if ( cscr->InputGlyphCount > ccsf2->MaxInputLength ) 24135569331642446be05292e3e1f8a51218827168cdclaireho ccsf2->MaxInputLength = cscr->InputGlyphCount; 24145569331642446be05292e3e1f8a51218827168cdclaireho 24155569331642446be05292e3e1f8a51218827168cdclaireho cscr->Input = NULL; 24165569331642446be05292e3e1f8a51218827168cdclaireho 24175569331642446be05292e3e1f8a51218827168cdclaireho count = cscr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */ 24185569331642446be05292e3e1f8a51218827168cdclaireho 24195569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( cscr->Input, count, HB_UShort ) ) 24205569331642446be05292e3e1f8a51218827168cdclaireho goto Fail4; 24215569331642446be05292e3e1f8a51218827168cdclaireho 24225569331642446be05292e3e1f8a51218827168cdclaireho i = cscr->Input; 24235569331642446be05292e3e1f8a51218827168cdclaireho 24245569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 2L ) ) 24255569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 24265569331642446be05292e3e1f8a51218827168cdclaireho 24275569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 24285569331642446be05292e3e1f8a51218827168cdclaireho i[n] = GET_UShort(); 24295569331642446be05292e3e1f8a51218827168cdclaireho 24305569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 24315569331642446be05292e3e1f8a51218827168cdclaireho 24325569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 24335569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 24345569331642446be05292e3e1f8a51218827168cdclaireho 24355569331642446be05292e3e1f8a51218827168cdclaireho cscr->LookaheadGlyphCount = GET_UShort(); 24365569331642446be05292e3e1f8a51218827168cdclaireho 24375569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 24385569331642446be05292e3e1f8a51218827168cdclaireho 24395569331642446be05292e3e1f8a51218827168cdclaireho if ( cscr->LookaheadGlyphCount > ccsf2->MaxLookaheadLength ) 24405569331642446be05292e3e1f8a51218827168cdclaireho ccsf2->MaxLookaheadLength = cscr->LookaheadGlyphCount; 24415569331642446be05292e3e1f8a51218827168cdclaireho 24425569331642446be05292e3e1f8a51218827168cdclaireho cscr->Lookahead = NULL; 24435569331642446be05292e3e1f8a51218827168cdclaireho 24445569331642446be05292e3e1f8a51218827168cdclaireho count = cscr->LookaheadGlyphCount; 24455569331642446be05292e3e1f8a51218827168cdclaireho 24465569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( cscr->Lookahead, count, HB_UShort ) ) 24475569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 24485569331642446be05292e3e1f8a51218827168cdclaireho 24495569331642446be05292e3e1f8a51218827168cdclaireho l = cscr->Lookahead; 24505569331642446be05292e3e1f8a51218827168cdclaireho 24515569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 2L ) ) 24525569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 24535569331642446be05292e3e1f8a51218827168cdclaireho 24545569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 24555569331642446be05292e3e1f8a51218827168cdclaireho l[n] = GET_UShort(); 24565569331642446be05292e3e1f8a51218827168cdclaireho 24575569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 24585569331642446be05292e3e1f8a51218827168cdclaireho 24595569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 24605569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 24615569331642446be05292e3e1f8a51218827168cdclaireho 24625569331642446be05292e3e1f8a51218827168cdclaireho cscr->SubstCount = GET_UShort(); 24635569331642446be05292e3e1f8a51218827168cdclaireho 24645569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 24655569331642446be05292e3e1f8a51218827168cdclaireho 24665569331642446be05292e3e1f8a51218827168cdclaireho cscr->SubstLookupRecord = NULL; 24675569331642446be05292e3e1f8a51218827168cdclaireho 24685569331642446be05292e3e1f8a51218827168cdclaireho count = cscr->SubstCount; 24695569331642446be05292e3e1f8a51218827168cdclaireho 24705569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( cscr->SubstLookupRecord, count, 24715569331642446be05292e3e1f8a51218827168cdclaireho HB_SubstLookupRecord ) ) 24725569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 24735569331642446be05292e3e1f8a51218827168cdclaireho 24745569331642446be05292e3e1f8a51218827168cdclaireho slr = cscr->SubstLookupRecord; 24755569331642446be05292e3e1f8a51218827168cdclaireho 24765569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 4L ) ) 24775569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 24785569331642446be05292e3e1f8a51218827168cdclaireho 24795569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 24805569331642446be05292e3e1f8a51218827168cdclaireho { 24815569331642446be05292e3e1f8a51218827168cdclaireho slr[n].SequenceIndex = GET_UShort(); 24825569331642446be05292e3e1f8a51218827168cdclaireho slr[n].LookupListIndex = GET_UShort(); 24835569331642446be05292e3e1f8a51218827168cdclaireho } 24845569331642446be05292e3e1f8a51218827168cdclaireho 24855569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 24865569331642446be05292e3e1f8a51218827168cdclaireho 24875569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 24885569331642446be05292e3e1f8a51218827168cdclaireho 24895569331642446be05292e3e1f8a51218827168cdclairehoFail1: 24905569331642446be05292e3e1f8a51218827168cdclaireho FREE( slr ); 24915569331642446be05292e3e1f8a51218827168cdclaireho 24925569331642446be05292e3e1f8a51218827168cdclairehoFail2: 24935569331642446be05292e3e1f8a51218827168cdclaireho FREE( l ); 24945569331642446be05292e3e1f8a51218827168cdclaireho 24955569331642446be05292e3e1f8a51218827168cdclairehoFail3: 24965569331642446be05292e3e1f8a51218827168cdclaireho FREE( i ); 24975569331642446be05292e3e1f8a51218827168cdclaireho 24985569331642446be05292e3e1f8a51218827168cdclairehoFail4: 24995569331642446be05292e3e1f8a51218827168cdclaireho FREE( b ); 25005569331642446be05292e3e1f8a51218827168cdclaireho return error; 25015569331642446be05292e3e1f8a51218827168cdclaireho} 25025569331642446be05292e3e1f8a51218827168cdclaireho 25035569331642446be05292e3e1f8a51218827168cdclaireho 25045569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_ChainSubClassRule( HB_ChainSubClassRule* cscr ) 25055569331642446be05292e3e1f8a51218827168cdclaireho{ 25065569331642446be05292e3e1f8a51218827168cdclaireho FREE( cscr->SubstLookupRecord ); 25075569331642446be05292e3e1f8a51218827168cdclaireho FREE( cscr->Lookahead ); 25085569331642446be05292e3e1f8a51218827168cdclaireho FREE( cscr->Input ); 25095569331642446be05292e3e1f8a51218827168cdclaireho FREE( cscr->Backtrack ); 25105569331642446be05292e3e1f8a51218827168cdclaireho} 25115569331642446be05292e3e1f8a51218827168cdclaireho 25125569331642446be05292e3e1f8a51218827168cdclaireho 25135569331642446be05292e3e1f8a51218827168cdclaireho/* SubClassSet */ 25145569331642446be05292e3e1f8a51218827168cdclaireho 25155569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_ChainSubClassSet( 25165569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainContextSubstFormat2* ccsf2, 25175569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainSubClassSet* cscs, 25185569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 25195569331642446be05292e3e1f8a51218827168cdclaireho{ 25205569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 25215569331642446be05292e3e1f8a51218827168cdclaireho 25225569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n = 0, m, count; 25235569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 25245569331642446be05292e3e1f8a51218827168cdclaireho 25255569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainSubClassRule* cscr; 25265569331642446be05292e3e1f8a51218827168cdclaireho 25275569331642446be05292e3e1f8a51218827168cdclaireho 25285569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 25295569331642446be05292e3e1f8a51218827168cdclaireho 25305569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 25315569331642446be05292e3e1f8a51218827168cdclaireho return error; 25325569331642446be05292e3e1f8a51218827168cdclaireho 25335569331642446be05292e3e1f8a51218827168cdclaireho count = cscs->ChainSubClassRuleCount = GET_UShort(); 25345569331642446be05292e3e1f8a51218827168cdclaireho 25355569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 25365569331642446be05292e3e1f8a51218827168cdclaireho 25375569331642446be05292e3e1f8a51218827168cdclaireho cscs->ChainSubClassRule = NULL; 25385569331642446be05292e3e1f8a51218827168cdclaireho 25395569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( cscs->ChainSubClassRule, count, 25405569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainSubClassRule ) ) 25415569331642446be05292e3e1f8a51218827168cdclaireho return error; 25425569331642446be05292e3e1f8a51218827168cdclaireho 25435569331642446be05292e3e1f8a51218827168cdclaireho cscr = cscs->ChainSubClassRule; 25445569331642446be05292e3e1f8a51218827168cdclaireho 25455569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 25465569331642446be05292e3e1f8a51218827168cdclaireho { 25475569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 25485569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 25495569331642446be05292e3e1f8a51218827168cdclaireho 25505569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 25515569331642446be05292e3e1f8a51218827168cdclaireho 25525569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 25535569331642446be05292e3e1f8a51218827168cdclaireho 25545569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 25555569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 25565569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_ChainSubClassRule( ccsf2, &cscr[n], 25575569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 25585569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 25595569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 25605569331642446be05292e3e1f8a51218827168cdclaireho } 25615569331642446be05292e3e1f8a51218827168cdclaireho 25625569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 25635569331642446be05292e3e1f8a51218827168cdclaireho 25645569331642446be05292e3e1f8a51218827168cdclairehoFail: 25655569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; m++ ) 25665569331642446be05292e3e1f8a51218827168cdclaireho Free_ChainSubClassRule( &cscr[m] ); 25675569331642446be05292e3e1f8a51218827168cdclaireho 25685569331642446be05292e3e1f8a51218827168cdclaireho FREE( cscr ); 25695569331642446be05292e3e1f8a51218827168cdclaireho return error; 25705569331642446be05292e3e1f8a51218827168cdclaireho} 25715569331642446be05292e3e1f8a51218827168cdclaireho 25725569331642446be05292e3e1f8a51218827168cdclaireho 25735569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_ChainSubClassSet( HB_ChainSubClassSet* cscs ) 25745569331642446be05292e3e1f8a51218827168cdclaireho{ 25755569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 25765569331642446be05292e3e1f8a51218827168cdclaireho 25775569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainSubClassRule* cscr; 25785569331642446be05292e3e1f8a51218827168cdclaireho 25795569331642446be05292e3e1f8a51218827168cdclaireho 25805569331642446be05292e3e1f8a51218827168cdclaireho if ( cscs->ChainSubClassRule ) 25815569331642446be05292e3e1f8a51218827168cdclaireho { 25825569331642446be05292e3e1f8a51218827168cdclaireho count = cscs->ChainSubClassRuleCount; 25835569331642446be05292e3e1f8a51218827168cdclaireho cscr = cscs->ChainSubClassRule; 25845569331642446be05292e3e1f8a51218827168cdclaireho 25855569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 25865569331642446be05292e3e1f8a51218827168cdclaireho Free_ChainSubClassRule( &cscr[n] ); 25875569331642446be05292e3e1f8a51218827168cdclaireho 25885569331642446be05292e3e1f8a51218827168cdclaireho FREE( cscr ); 25895569331642446be05292e3e1f8a51218827168cdclaireho } 25905569331642446be05292e3e1f8a51218827168cdclaireho} 25915569331642446be05292e3e1f8a51218827168cdclaireho 25925569331642446be05292e3e1f8a51218827168cdclaireho 25935569331642446be05292e3e1f8a51218827168cdclaireho/* ChainContextSubstFormat2 */ 25945569331642446be05292e3e1f8a51218827168cdclaireho 25955569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_ChainContextSubst2( 25965569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainContextSubstFormat2* ccsf2, 25975569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 25985569331642446be05292e3e1f8a51218827168cdclaireho{ 25995569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 26005569331642446be05292e3e1f8a51218827168cdclaireho 26015569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n = 0, m, count; 26025569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 26035569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt backtrack_offset, input_offset, lookahead_offset; 26045569331642446be05292e3e1f8a51218827168cdclaireho 26055569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainSubClassSet* cscs; 26065569331642446be05292e3e1f8a51218827168cdclaireho 26075569331642446be05292e3e1f8a51218827168cdclaireho 26085569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos() - 2; 26095569331642446be05292e3e1f8a51218827168cdclaireho 26105569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 26115569331642446be05292e3e1f8a51218827168cdclaireho return error; 26125569331642446be05292e3e1f8a51218827168cdclaireho 26135569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 26145569331642446be05292e3e1f8a51218827168cdclaireho 26155569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 26165569331642446be05292e3e1f8a51218827168cdclaireho 26175569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 26185569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 26195569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &ccsf2->Coverage, stream ) ) != HB_Err_Ok ) 26205569331642446be05292e3e1f8a51218827168cdclaireho return error; 26215569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 26225569331642446be05292e3e1f8a51218827168cdclaireho 26235569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 8L ) ) 26245569331642446be05292e3e1f8a51218827168cdclaireho goto Fail5; 26255569331642446be05292e3e1f8a51218827168cdclaireho 26265569331642446be05292e3e1f8a51218827168cdclaireho backtrack_offset = GET_UShort(); 26275569331642446be05292e3e1f8a51218827168cdclaireho input_offset = GET_UShort(); 26285569331642446be05292e3e1f8a51218827168cdclaireho lookahead_offset = GET_UShort(); 26295569331642446be05292e3e1f8a51218827168cdclaireho 26305569331642446be05292e3e1f8a51218827168cdclaireho /* `ChainSubClassSetCount' is the upper limit for input class values, 26315569331642446be05292e3e1f8a51218827168cdclaireho thus we read it now to make an additional safety check. No limit 26325569331642446be05292e3e1f8a51218827168cdclaireho is known or needed for the other two class definitions */ 26335569331642446be05292e3e1f8a51218827168cdclaireho 26345569331642446be05292e3e1f8a51218827168cdclaireho count = ccsf2->ChainSubClassSetCount = GET_UShort(); 26355569331642446be05292e3e1f8a51218827168cdclaireho 26365569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 26375569331642446be05292e3e1f8a51218827168cdclaireho 26385569331642446be05292e3e1f8a51218827168cdclaireho if ( ( error = _HB_OPEN_Load_EmptyOrClassDefinition( &ccsf2->BacktrackClassDef, 65535, 26395569331642446be05292e3e1f8a51218827168cdclaireho backtrack_offset, base_offset, 26405569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 26415569331642446be05292e3e1f8a51218827168cdclaireho goto Fail5; 26425569331642446be05292e3e1f8a51218827168cdclaireho 26435569331642446be05292e3e1f8a51218827168cdclaireho if ( ( error = _HB_OPEN_Load_EmptyOrClassDefinition( &ccsf2->InputClassDef, count, 26445569331642446be05292e3e1f8a51218827168cdclaireho input_offset, base_offset, 26455569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 26465569331642446be05292e3e1f8a51218827168cdclaireho goto Fail4; 26475569331642446be05292e3e1f8a51218827168cdclaireho if ( ( error = _HB_OPEN_Load_EmptyOrClassDefinition( &ccsf2->LookaheadClassDef, 65535, 26485569331642446be05292e3e1f8a51218827168cdclaireho lookahead_offset, base_offset, 26495569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 26505569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 26515569331642446be05292e3e1f8a51218827168cdclaireho 26525569331642446be05292e3e1f8a51218827168cdclaireho ccsf2->ChainSubClassSet = NULL; 26535569331642446be05292e3e1f8a51218827168cdclaireho ccsf2->MaxBacktrackLength = 0; 26545569331642446be05292e3e1f8a51218827168cdclaireho ccsf2->MaxInputLength = 0; 26555569331642446be05292e3e1f8a51218827168cdclaireho ccsf2->MaxLookaheadLength = 0; 26565569331642446be05292e3e1f8a51218827168cdclaireho 26575569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( ccsf2->ChainSubClassSet, count, HB_ChainSubClassSet ) ) 26585569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 26595569331642446be05292e3e1f8a51218827168cdclaireho 26605569331642446be05292e3e1f8a51218827168cdclaireho cscs = ccsf2->ChainSubClassSet; 26615569331642446be05292e3e1f8a51218827168cdclaireho 26625569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 26635569331642446be05292e3e1f8a51218827168cdclaireho { 26645569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 26655569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 26665569331642446be05292e3e1f8a51218827168cdclaireho 26675569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 26685569331642446be05292e3e1f8a51218827168cdclaireho 26695569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 26705569331642446be05292e3e1f8a51218827168cdclaireho 26715569331642446be05292e3e1f8a51218827168cdclaireho if ( new_offset != base_offset ) /* not a NULL offset */ 26725569331642446be05292e3e1f8a51218827168cdclaireho { 26735569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 26745569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 26755569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_ChainSubClassSet( ccsf2, &cscs[n], 26765569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 26775569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 26785569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 26795569331642446be05292e3e1f8a51218827168cdclaireho } 26805569331642446be05292e3e1f8a51218827168cdclaireho else 26815569331642446be05292e3e1f8a51218827168cdclaireho { 26825569331642446be05292e3e1f8a51218827168cdclaireho /* we create a ChainSubClassSet table with no entries */ 26835569331642446be05292e3e1f8a51218827168cdclaireho 26845569331642446be05292e3e1f8a51218827168cdclaireho ccsf2->ChainSubClassSet[n].ChainSubClassRuleCount = 0; 26855569331642446be05292e3e1f8a51218827168cdclaireho ccsf2->ChainSubClassSet[n].ChainSubClassRule = NULL; 26865569331642446be05292e3e1f8a51218827168cdclaireho } 26875569331642446be05292e3e1f8a51218827168cdclaireho } 26885569331642446be05292e3e1f8a51218827168cdclaireho 26895569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 26905569331642446be05292e3e1f8a51218827168cdclaireho 26915569331642446be05292e3e1f8a51218827168cdclairehoFail1: 26925569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; m++ ) 26935569331642446be05292e3e1f8a51218827168cdclaireho Free_ChainSubClassSet( &cscs[m] ); 26945569331642446be05292e3e1f8a51218827168cdclaireho 26955569331642446be05292e3e1f8a51218827168cdclaireho FREE( cscs ); 26965569331642446be05292e3e1f8a51218827168cdclaireho 26975569331642446be05292e3e1f8a51218827168cdclairehoFail2: 26985569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_ClassDefinition( &ccsf2->LookaheadClassDef ); 26995569331642446be05292e3e1f8a51218827168cdclaireho 27005569331642446be05292e3e1f8a51218827168cdclairehoFail3: 27015569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_ClassDefinition( &ccsf2->InputClassDef ); 27025569331642446be05292e3e1f8a51218827168cdclaireho 27035569331642446be05292e3e1f8a51218827168cdclairehoFail4: 27045569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_ClassDefinition( &ccsf2->BacktrackClassDef ); 27055569331642446be05292e3e1f8a51218827168cdclaireho 27065569331642446be05292e3e1f8a51218827168cdclairehoFail5: 27075569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &ccsf2->Coverage ); 27085569331642446be05292e3e1f8a51218827168cdclaireho return error; 27095569331642446be05292e3e1f8a51218827168cdclaireho} 27105569331642446be05292e3e1f8a51218827168cdclaireho 27115569331642446be05292e3e1f8a51218827168cdclaireho 27125569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_ChainContextSubst2( HB_ChainContextSubstFormat2* ccsf2 ) 27135569331642446be05292e3e1f8a51218827168cdclaireho{ 27145569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 27155569331642446be05292e3e1f8a51218827168cdclaireho 27165569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainSubClassSet* cscs; 27175569331642446be05292e3e1f8a51218827168cdclaireho 27185569331642446be05292e3e1f8a51218827168cdclaireho 27195569331642446be05292e3e1f8a51218827168cdclaireho if ( ccsf2->ChainSubClassSet ) 27205569331642446be05292e3e1f8a51218827168cdclaireho { 27215569331642446be05292e3e1f8a51218827168cdclaireho count = ccsf2->ChainSubClassSetCount; 27225569331642446be05292e3e1f8a51218827168cdclaireho cscs = ccsf2->ChainSubClassSet; 27235569331642446be05292e3e1f8a51218827168cdclaireho 27245569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 27255569331642446be05292e3e1f8a51218827168cdclaireho Free_ChainSubClassSet( &cscs[n] ); 27265569331642446be05292e3e1f8a51218827168cdclaireho 27275569331642446be05292e3e1f8a51218827168cdclaireho FREE( cscs ); 27285569331642446be05292e3e1f8a51218827168cdclaireho } 27295569331642446be05292e3e1f8a51218827168cdclaireho 27305569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_ClassDefinition( &ccsf2->LookaheadClassDef ); 27315569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_ClassDefinition( &ccsf2->InputClassDef ); 27325569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_ClassDefinition( &ccsf2->BacktrackClassDef ); 27335569331642446be05292e3e1f8a51218827168cdclaireho 27345569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &ccsf2->Coverage ); 27355569331642446be05292e3e1f8a51218827168cdclaireho} 27365569331642446be05292e3e1f8a51218827168cdclaireho 27375569331642446be05292e3e1f8a51218827168cdclaireho 27385569331642446be05292e3e1f8a51218827168cdclaireho/* ChainContextSubstFormat3 */ 27395569331642446be05292e3e1f8a51218827168cdclaireho 27405569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_ChainContextSubst3( 27415569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainContextSubstFormat3* ccsf3, 27425569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 27435569331642446be05292e3e1f8a51218827168cdclaireho{ 27445569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 27455569331642446be05292e3e1f8a51218827168cdclaireho 27465569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, nb = 0, ni =0, nl = 0, m, count; 27475569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort backtrack_count, input_count, lookahead_count; 27485569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 27495569331642446be05292e3e1f8a51218827168cdclaireho 27505569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage* b; 27515569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage* i; 27525569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage* l; 27535569331642446be05292e3e1f8a51218827168cdclaireho HB_SubstLookupRecord* slr; 27545569331642446be05292e3e1f8a51218827168cdclaireho 27555569331642446be05292e3e1f8a51218827168cdclaireho 27565569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos() - 2L; 27575569331642446be05292e3e1f8a51218827168cdclaireho 27585569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 27595569331642446be05292e3e1f8a51218827168cdclaireho return error; 27605569331642446be05292e3e1f8a51218827168cdclaireho 27615569331642446be05292e3e1f8a51218827168cdclaireho ccsf3->BacktrackGlyphCount = GET_UShort(); 27625569331642446be05292e3e1f8a51218827168cdclaireho 27635569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 27645569331642446be05292e3e1f8a51218827168cdclaireho 27655569331642446be05292e3e1f8a51218827168cdclaireho ccsf3->BacktrackCoverage = NULL; 27665569331642446be05292e3e1f8a51218827168cdclaireho 27675569331642446be05292e3e1f8a51218827168cdclaireho backtrack_count = ccsf3->BacktrackGlyphCount; 27685569331642446be05292e3e1f8a51218827168cdclaireho 27695569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( ccsf3->BacktrackCoverage, backtrack_count, 27705569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage ) ) 27715569331642446be05292e3e1f8a51218827168cdclaireho return error; 27725569331642446be05292e3e1f8a51218827168cdclaireho 27735569331642446be05292e3e1f8a51218827168cdclaireho b = ccsf3->BacktrackCoverage; 27745569331642446be05292e3e1f8a51218827168cdclaireho 27755569331642446be05292e3e1f8a51218827168cdclaireho for ( nb = 0; nb < backtrack_count; nb++ ) 27765569331642446be05292e3e1f8a51218827168cdclaireho { 27775569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 27785569331642446be05292e3e1f8a51218827168cdclaireho goto Fail4; 27795569331642446be05292e3e1f8a51218827168cdclaireho 27805569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 27815569331642446be05292e3e1f8a51218827168cdclaireho 27825569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 27835569331642446be05292e3e1f8a51218827168cdclaireho 27845569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 27855569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 27865569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &b[nb], stream ) ) != HB_Err_Ok ) 27875569331642446be05292e3e1f8a51218827168cdclaireho goto Fail4; 27885569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 27895569331642446be05292e3e1f8a51218827168cdclaireho } 27905569331642446be05292e3e1f8a51218827168cdclaireho 27915569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 27925569331642446be05292e3e1f8a51218827168cdclaireho goto Fail4; 27935569331642446be05292e3e1f8a51218827168cdclaireho 27945569331642446be05292e3e1f8a51218827168cdclaireho ccsf3->InputGlyphCount = GET_UShort(); 27955569331642446be05292e3e1f8a51218827168cdclaireho 27965569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 27975569331642446be05292e3e1f8a51218827168cdclaireho 27985569331642446be05292e3e1f8a51218827168cdclaireho ccsf3->InputCoverage = NULL; 27995569331642446be05292e3e1f8a51218827168cdclaireho 28005569331642446be05292e3e1f8a51218827168cdclaireho input_count = ccsf3->InputGlyphCount; 28015569331642446be05292e3e1f8a51218827168cdclaireho 28025569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( ccsf3->InputCoverage, input_count, HB_Coverage ) ) 28035569331642446be05292e3e1f8a51218827168cdclaireho goto Fail4; 28045569331642446be05292e3e1f8a51218827168cdclaireho 28055569331642446be05292e3e1f8a51218827168cdclaireho i = ccsf3->InputCoverage; 28065569331642446be05292e3e1f8a51218827168cdclaireho 28075569331642446be05292e3e1f8a51218827168cdclaireho for ( ni = 0; ni < input_count; ni++ ) 28085569331642446be05292e3e1f8a51218827168cdclaireho { 28095569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 28105569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 28115569331642446be05292e3e1f8a51218827168cdclaireho 28125569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 28135569331642446be05292e3e1f8a51218827168cdclaireho 28145569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 28155569331642446be05292e3e1f8a51218827168cdclaireho 28165569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 28175569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 28185569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &i[ni], stream ) ) != HB_Err_Ok ) 28195569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 28205569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 28215569331642446be05292e3e1f8a51218827168cdclaireho } 28225569331642446be05292e3e1f8a51218827168cdclaireho 28235569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 28245569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 28255569331642446be05292e3e1f8a51218827168cdclaireho 28265569331642446be05292e3e1f8a51218827168cdclaireho ccsf3->LookaheadGlyphCount = GET_UShort(); 28275569331642446be05292e3e1f8a51218827168cdclaireho 28285569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 28295569331642446be05292e3e1f8a51218827168cdclaireho 28305569331642446be05292e3e1f8a51218827168cdclaireho ccsf3->LookaheadCoverage = NULL; 28315569331642446be05292e3e1f8a51218827168cdclaireho 28325569331642446be05292e3e1f8a51218827168cdclaireho lookahead_count = ccsf3->LookaheadGlyphCount; 28335569331642446be05292e3e1f8a51218827168cdclaireho 28345569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( ccsf3->LookaheadCoverage, lookahead_count, 28355569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage ) ) 28365569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 28375569331642446be05292e3e1f8a51218827168cdclaireho 28385569331642446be05292e3e1f8a51218827168cdclaireho l = ccsf3->LookaheadCoverage; 28395569331642446be05292e3e1f8a51218827168cdclaireho 28405569331642446be05292e3e1f8a51218827168cdclaireho for ( nl = 0; nl < lookahead_count; nl++ ) 28415569331642446be05292e3e1f8a51218827168cdclaireho { 28425569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 28435569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 28445569331642446be05292e3e1f8a51218827168cdclaireho 28455569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 28465569331642446be05292e3e1f8a51218827168cdclaireho 28475569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 28485569331642446be05292e3e1f8a51218827168cdclaireho 28495569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 28505569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 28515569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &l[nl], stream ) ) != HB_Err_Ok ) 28525569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 28535569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 28545569331642446be05292e3e1f8a51218827168cdclaireho } 28555569331642446be05292e3e1f8a51218827168cdclaireho 28565569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 28575569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 28585569331642446be05292e3e1f8a51218827168cdclaireho 28595569331642446be05292e3e1f8a51218827168cdclaireho ccsf3->SubstCount = GET_UShort(); 28605569331642446be05292e3e1f8a51218827168cdclaireho 28615569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 28625569331642446be05292e3e1f8a51218827168cdclaireho 28635569331642446be05292e3e1f8a51218827168cdclaireho ccsf3->SubstLookupRecord = NULL; 28645569331642446be05292e3e1f8a51218827168cdclaireho 28655569331642446be05292e3e1f8a51218827168cdclaireho count = ccsf3->SubstCount; 28665569331642446be05292e3e1f8a51218827168cdclaireho 28675569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( ccsf3->SubstLookupRecord, count, 28685569331642446be05292e3e1f8a51218827168cdclaireho HB_SubstLookupRecord ) ) 28695569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 28705569331642446be05292e3e1f8a51218827168cdclaireho 28715569331642446be05292e3e1f8a51218827168cdclaireho slr = ccsf3->SubstLookupRecord; 28725569331642446be05292e3e1f8a51218827168cdclaireho 28735569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 4L ) ) 28745569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 28755569331642446be05292e3e1f8a51218827168cdclaireho 28765569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 28775569331642446be05292e3e1f8a51218827168cdclaireho { 28785569331642446be05292e3e1f8a51218827168cdclaireho slr[n].SequenceIndex = GET_UShort(); 28795569331642446be05292e3e1f8a51218827168cdclaireho slr[n].LookupListIndex = GET_UShort(); 28805569331642446be05292e3e1f8a51218827168cdclaireho } 28815569331642446be05292e3e1f8a51218827168cdclaireho 28825569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 28835569331642446be05292e3e1f8a51218827168cdclaireho 28845569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 28855569331642446be05292e3e1f8a51218827168cdclaireho 28865569331642446be05292e3e1f8a51218827168cdclairehoFail1: 28875569331642446be05292e3e1f8a51218827168cdclaireho FREE( slr ); 28885569331642446be05292e3e1f8a51218827168cdclaireho 28895569331642446be05292e3e1f8a51218827168cdclairehoFail2: 28905569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < nl; m++ ) 28915569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &l[m] ); 28925569331642446be05292e3e1f8a51218827168cdclaireho 28935569331642446be05292e3e1f8a51218827168cdclaireho FREE( l ); 28945569331642446be05292e3e1f8a51218827168cdclaireho 28955569331642446be05292e3e1f8a51218827168cdclairehoFail3: 28965569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < ni; m++ ) 28975569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &i[m] ); 28985569331642446be05292e3e1f8a51218827168cdclaireho 28995569331642446be05292e3e1f8a51218827168cdclaireho FREE( i ); 29005569331642446be05292e3e1f8a51218827168cdclaireho 29015569331642446be05292e3e1f8a51218827168cdclairehoFail4: 29025569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < nb; m++ ) 29035569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &b[m] ); 29045569331642446be05292e3e1f8a51218827168cdclaireho 29055569331642446be05292e3e1f8a51218827168cdclaireho FREE( b ); 29065569331642446be05292e3e1f8a51218827168cdclaireho return error; 29075569331642446be05292e3e1f8a51218827168cdclaireho} 29085569331642446be05292e3e1f8a51218827168cdclaireho 29095569331642446be05292e3e1f8a51218827168cdclaireho 29105569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_ChainContextSubst3( HB_ChainContextSubstFormat3* ccsf3 ) 29115569331642446be05292e3e1f8a51218827168cdclaireho{ 29125569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 29135569331642446be05292e3e1f8a51218827168cdclaireho 29145569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage* c; 29155569331642446be05292e3e1f8a51218827168cdclaireho 29165569331642446be05292e3e1f8a51218827168cdclaireho 29175569331642446be05292e3e1f8a51218827168cdclaireho FREE( ccsf3->SubstLookupRecord ); 29185569331642446be05292e3e1f8a51218827168cdclaireho 29195569331642446be05292e3e1f8a51218827168cdclaireho if ( ccsf3->LookaheadCoverage ) 29205569331642446be05292e3e1f8a51218827168cdclaireho { 29215569331642446be05292e3e1f8a51218827168cdclaireho count = ccsf3->LookaheadGlyphCount; 29225569331642446be05292e3e1f8a51218827168cdclaireho c = ccsf3->LookaheadCoverage; 29235569331642446be05292e3e1f8a51218827168cdclaireho 29245569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 29255569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &c[n] ); 29265569331642446be05292e3e1f8a51218827168cdclaireho 29275569331642446be05292e3e1f8a51218827168cdclaireho FREE( c ); 29285569331642446be05292e3e1f8a51218827168cdclaireho } 29295569331642446be05292e3e1f8a51218827168cdclaireho 29305569331642446be05292e3e1f8a51218827168cdclaireho if ( ccsf3->InputCoverage ) 29315569331642446be05292e3e1f8a51218827168cdclaireho { 29325569331642446be05292e3e1f8a51218827168cdclaireho count = ccsf3->InputGlyphCount; 29335569331642446be05292e3e1f8a51218827168cdclaireho c = ccsf3->InputCoverage; 29345569331642446be05292e3e1f8a51218827168cdclaireho 29355569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 29365569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &c[n] ); 29375569331642446be05292e3e1f8a51218827168cdclaireho 29385569331642446be05292e3e1f8a51218827168cdclaireho FREE( c ); 29395569331642446be05292e3e1f8a51218827168cdclaireho } 29405569331642446be05292e3e1f8a51218827168cdclaireho 29415569331642446be05292e3e1f8a51218827168cdclaireho if ( ccsf3->BacktrackCoverage ) 29425569331642446be05292e3e1f8a51218827168cdclaireho { 29435569331642446be05292e3e1f8a51218827168cdclaireho count = ccsf3->BacktrackGlyphCount; 29445569331642446be05292e3e1f8a51218827168cdclaireho c = ccsf3->BacktrackCoverage; 29455569331642446be05292e3e1f8a51218827168cdclaireho 29465569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 29475569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &c[n] ); 29485569331642446be05292e3e1f8a51218827168cdclaireho 29495569331642446be05292e3e1f8a51218827168cdclaireho FREE( c ); 29505569331642446be05292e3e1f8a51218827168cdclaireho } 29515569331642446be05292e3e1f8a51218827168cdclaireho} 29525569331642446be05292e3e1f8a51218827168cdclaireho 29535569331642446be05292e3e1f8a51218827168cdclaireho 29545569331642446be05292e3e1f8a51218827168cdclaireho/* ChainContextSubst */ 29555569331642446be05292e3e1f8a51218827168cdclaireho 29565569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_ChainContextSubst( HB_GSUB_SubTable* st, 29575569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 29585569331642446be05292e3e1f8a51218827168cdclaireho{ 29595569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 29605569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainContextSubst* ccs = &st->chain; 29615569331642446be05292e3e1f8a51218827168cdclaireho 29625569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 29635569331642446be05292e3e1f8a51218827168cdclaireho return error; 29645569331642446be05292e3e1f8a51218827168cdclaireho 29655569331642446be05292e3e1f8a51218827168cdclaireho ccs->SubstFormat = GET_UShort(); 29665569331642446be05292e3e1f8a51218827168cdclaireho 29675569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 29685569331642446be05292e3e1f8a51218827168cdclaireho 29695569331642446be05292e3e1f8a51218827168cdclaireho switch ( ccs->SubstFormat ) { 29705569331642446be05292e3e1f8a51218827168cdclaireho case 1: return Load_ChainContextSubst1( &ccs->ccsf.ccsf1, stream ); 29715569331642446be05292e3e1f8a51218827168cdclaireho case 2: return Load_ChainContextSubst2( &ccs->ccsf.ccsf2, stream ); 29725569331642446be05292e3e1f8a51218827168cdclaireho case 3: return Load_ChainContextSubst3( &ccs->ccsf.ccsf3, stream ); 29735569331642446be05292e3e1f8a51218827168cdclaireho default: return ERR(HB_Err_Invalid_SubTable_Format); 29745569331642446be05292e3e1f8a51218827168cdclaireho } 29755569331642446be05292e3e1f8a51218827168cdclaireho 29765569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; /* never reached */ 29775569331642446be05292e3e1f8a51218827168cdclaireho} 29785569331642446be05292e3e1f8a51218827168cdclaireho 29795569331642446be05292e3e1f8a51218827168cdclaireho 29805569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_ChainContextSubst( HB_GSUB_SubTable* st ) 29815569331642446be05292e3e1f8a51218827168cdclaireho{ 29825569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainContextSubst* ccs = &st->chain; 29835569331642446be05292e3e1f8a51218827168cdclaireho 29845569331642446be05292e3e1f8a51218827168cdclaireho switch ( ccs->SubstFormat ) { 29855569331642446be05292e3e1f8a51218827168cdclaireho case 1: Free_ChainContextSubst1( &ccs->ccsf.ccsf1 ); break; 29865569331642446be05292e3e1f8a51218827168cdclaireho case 2: Free_ChainContextSubst2( &ccs->ccsf.ccsf2 ); break; 29875569331642446be05292e3e1f8a51218827168cdclaireho case 3: Free_ChainContextSubst3( &ccs->ccsf.ccsf3 ); break; 29885569331642446be05292e3e1f8a51218827168cdclaireho default: break; 29895569331642446be05292e3e1f8a51218827168cdclaireho } 29905569331642446be05292e3e1f8a51218827168cdclaireho} 29915569331642446be05292e3e1f8a51218827168cdclaireho 29925569331642446be05292e3e1f8a51218827168cdclaireho 29935569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Lookup_ChainContextSubst1( HB_GSUBHeader* gsub, 29945569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainContextSubstFormat1* ccsf1, 29955569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 29965569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort flags, 29975569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 29985569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 29995569331642446be05292e3e1f8a51218827168cdclaireho{ 30005569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort index, property; 30015569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort i, j, k, num_csr; 30025569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort bgc, igc, lgc; 30035569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 30045569331642446be05292e3e1f8a51218827168cdclaireho 30055569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainSubRule* csr; 30065569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainSubRule curr_csr; 30075569331642446be05292e3e1f8a51218827168cdclaireho HB_GDEFHeader* gdef; 30085569331642446be05292e3e1f8a51218827168cdclaireho 30095569331642446be05292e3e1f8a51218827168cdclaireho 30105569331642446be05292e3e1f8a51218827168cdclaireho gdef = gsub->gdef; 30115569331642446be05292e3e1f8a51218827168cdclaireho 30125569331642446be05292e3e1f8a51218827168cdclaireho if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) 30135569331642446be05292e3e1f8a51218827168cdclaireho return error; 30145569331642446be05292e3e1f8a51218827168cdclaireho 30155569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &ccsf1->Coverage, IN_CURGLYPH(), &index ); 30165569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 30175569331642446be05292e3e1f8a51218827168cdclaireho return error; 30185569331642446be05292e3e1f8a51218827168cdclaireho 30195569331642446be05292e3e1f8a51218827168cdclaireho csr = ccsf1->ChainSubRuleSet[index].ChainSubRule; 30205569331642446be05292e3e1f8a51218827168cdclaireho num_csr = ccsf1->ChainSubRuleSet[index].ChainSubRuleCount; 30215569331642446be05292e3e1f8a51218827168cdclaireho 30225569331642446be05292e3e1f8a51218827168cdclaireho for ( k = 0; k < num_csr; k++ ) 30235569331642446be05292e3e1f8a51218827168cdclaireho { 30245569331642446be05292e3e1f8a51218827168cdclaireho curr_csr = csr[k]; 30255569331642446be05292e3e1f8a51218827168cdclaireho bgc = curr_csr.BacktrackGlyphCount; 30265569331642446be05292e3e1f8a51218827168cdclaireho igc = curr_csr.InputGlyphCount; 30275569331642446be05292e3e1f8a51218827168cdclaireho lgc = curr_csr.LookaheadGlyphCount; 30285569331642446be05292e3e1f8a51218827168cdclaireho 30295569331642446be05292e3e1f8a51218827168cdclaireho if ( context_length != 0xFFFF && context_length < igc ) 30305569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainsubrule; 30315569331642446be05292e3e1f8a51218827168cdclaireho 30325569331642446be05292e3e1f8a51218827168cdclaireho /* check whether context is too long; it is a first guess only */ 30335569331642446be05292e3e1f8a51218827168cdclaireho 30345569331642446be05292e3e1f8a51218827168cdclaireho if ( bgc > buffer->out_pos || buffer->in_pos + igc + lgc > buffer->in_length ) 30355569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainsubrule; 30365569331642446be05292e3e1f8a51218827168cdclaireho 30375569331642446be05292e3e1f8a51218827168cdclaireho if ( bgc ) 30385569331642446be05292e3e1f8a51218827168cdclaireho { 30395569331642446be05292e3e1f8a51218827168cdclaireho /* since we don't know in advance the number of glyphs to inspect, 30405569331642446be05292e3e1f8a51218827168cdclaireho we search backwards for matches in the backtrack glyph array */ 30415569331642446be05292e3e1f8a51218827168cdclaireho 30425569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 0, j = buffer->out_pos - 1; i < bgc; i++, j-- ) 30435569331642446be05292e3e1f8a51218827168cdclaireho { 30445569331642446be05292e3e1f8a51218827168cdclaireho while ( CHECK_Property( gdef, OUT_ITEM( j ), flags, &property ) ) 30455569331642446be05292e3e1f8a51218827168cdclaireho { 30465569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 30475569331642446be05292e3e1f8a51218827168cdclaireho return error; 30485569331642446be05292e3e1f8a51218827168cdclaireho 30495569331642446be05292e3e1f8a51218827168cdclaireho if ( j + 1 == bgc - i ) 30505569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainsubrule; 30515569331642446be05292e3e1f8a51218827168cdclaireho j--; 30525569331642446be05292e3e1f8a51218827168cdclaireho } 30535569331642446be05292e3e1f8a51218827168cdclaireho 30545569331642446be05292e3e1f8a51218827168cdclaireho /* In OpenType 1.3, it is undefined whether the offsets of 30555569331642446be05292e3e1f8a51218827168cdclaireho backtrack glyphs is in logical order or not. Version 1.4 30565569331642446be05292e3e1f8a51218827168cdclaireho will clarify this: 30575569331642446be05292e3e1f8a51218827168cdclaireho 30585569331642446be05292e3e1f8a51218827168cdclaireho Logical order - a b c d e f g h i j 30595569331642446be05292e3e1f8a51218827168cdclaireho i 30605569331642446be05292e3e1f8a51218827168cdclaireho Input offsets - 0 1 30615569331642446be05292e3e1f8a51218827168cdclaireho Backtrack offsets - 3 2 1 0 30625569331642446be05292e3e1f8a51218827168cdclaireho Lookahead offsets - 0 1 2 3 */ 30635569331642446be05292e3e1f8a51218827168cdclaireho 30645569331642446be05292e3e1f8a51218827168cdclaireho if ( OUT_GLYPH( j ) != curr_csr.Backtrack[i] ) 30655569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainsubrule; 30665569331642446be05292e3e1f8a51218827168cdclaireho } 30675569331642446be05292e3e1f8a51218827168cdclaireho } 30685569331642446be05292e3e1f8a51218827168cdclaireho 30695569331642446be05292e3e1f8a51218827168cdclaireho /* Start at 1 because [0] is implied */ 30705569331642446be05292e3e1f8a51218827168cdclaireho 30715569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 1, j = buffer->in_pos + 1; i < igc; i++, j++ ) 30725569331642446be05292e3e1f8a51218827168cdclaireho { 30735569331642446be05292e3e1f8a51218827168cdclaireho while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) 30745569331642446be05292e3e1f8a51218827168cdclaireho { 30755569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 30765569331642446be05292e3e1f8a51218827168cdclaireho return error; 30775569331642446be05292e3e1f8a51218827168cdclaireho 30785569331642446be05292e3e1f8a51218827168cdclaireho if ( j + igc - i + lgc == (HB_Int)buffer->in_length ) 30795569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainsubrule; 30805569331642446be05292e3e1f8a51218827168cdclaireho j++; 30815569331642446be05292e3e1f8a51218827168cdclaireho } 30825569331642446be05292e3e1f8a51218827168cdclaireho 30835569331642446be05292e3e1f8a51218827168cdclaireho if ( IN_GLYPH( j ) != curr_csr.Input[i - 1] ) 30845569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainsubrule; 30855569331642446be05292e3e1f8a51218827168cdclaireho } 30865569331642446be05292e3e1f8a51218827168cdclaireho 30875569331642446be05292e3e1f8a51218827168cdclaireho /* we are starting to check for lookahead glyphs right after the 30885569331642446be05292e3e1f8a51218827168cdclaireho last context glyph */ 30895569331642446be05292e3e1f8a51218827168cdclaireho 30905569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 0; i < lgc; i++, j++ ) 30915569331642446be05292e3e1f8a51218827168cdclaireho { 30925569331642446be05292e3e1f8a51218827168cdclaireho while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) 30935569331642446be05292e3e1f8a51218827168cdclaireho { 30945569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 30955569331642446be05292e3e1f8a51218827168cdclaireho return error; 30965569331642446be05292e3e1f8a51218827168cdclaireho 30975569331642446be05292e3e1f8a51218827168cdclaireho if ( j + lgc - i == (HB_Int)buffer->in_length ) 30985569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainsubrule; 30995569331642446be05292e3e1f8a51218827168cdclaireho j++; 31005569331642446be05292e3e1f8a51218827168cdclaireho } 31015569331642446be05292e3e1f8a51218827168cdclaireho 31025569331642446be05292e3e1f8a51218827168cdclaireho if ( IN_GLYPH( j ) != curr_csr.Lookahead[i] ) 31035569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainsubrule; 31045569331642446be05292e3e1f8a51218827168cdclaireho } 31055569331642446be05292e3e1f8a51218827168cdclaireho 31065569331642446be05292e3e1f8a51218827168cdclaireho return Do_ContextSubst( gsub, igc, 31075569331642446be05292e3e1f8a51218827168cdclaireho curr_csr.SubstCount, 31085569331642446be05292e3e1f8a51218827168cdclaireho curr_csr.SubstLookupRecord, 31095569331642446be05292e3e1f8a51218827168cdclaireho buffer, 31105569331642446be05292e3e1f8a51218827168cdclaireho nesting_level ); 31115569331642446be05292e3e1f8a51218827168cdclaireho 31125569331642446be05292e3e1f8a51218827168cdclaireho next_chainsubrule: 31135569331642446be05292e3e1f8a51218827168cdclaireho ; 31145569331642446be05292e3e1f8a51218827168cdclaireho } 31155569331642446be05292e3e1f8a51218827168cdclaireho 31165569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 31175569331642446be05292e3e1f8a51218827168cdclaireho} 31185569331642446be05292e3e1f8a51218827168cdclaireho 31195569331642446be05292e3e1f8a51218827168cdclaireho 31205569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Lookup_ChainContextSubst2( HB_GSUBHeader* gsub, 31215569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainContextSubstFormat2* ccsf2, 31225569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 31235569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort flags, 31245569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 31255569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 31265569331642446be05292e3e1f8a51218827168cdclaireho{ 31275569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort index, property; 31285569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 31295569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort i, j, k; 31305569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort bgc, igc, lgc; 31315569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort known_backtrack_classes, 31325569331642446be05292e3e1f8a51218827168cdclaireho known_input_classes, 31335569331642446be05292e3e1f8a51218827168cdclaireho known_lookahead_classes; 31345569331642446be05292e3e1f8a51218827168cdclaireho 31355569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* backtrack_classes; 31365569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* input_classes; 31375569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* lookahead_classes; 31385569331642446be05292e3e1f8a51218827168cdclaireho 31395569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* bc; 31405569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* ic; 31415569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* lc; 31425569331642446be05292e3e1f8a51218827168cdclaireho 31435569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainSubClassSet* cscs; 31445569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainSubClassRule ccsr; 31455569331642446be05292e3e1f8a51218827168cdclaireho HB_GDEFHeader* gdef; 31465569331642446be05292e3e1f8a51218827168cdclaireho 31475569331642446be05292e3e1f8a51218827168cdclaireho 31485569331642446be05292e3e1f8a51218827168cdclaireho gdef = gsub->gdef; 31495569331642446be05292e3e1f8a51218827168cdclaireho 31505569331642446be05292e3e1f8a51218827168cdclaireho if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) 31515569331642446be05292e3e1f8a51218827168cdclaireho return error; 31525569331642446be05292e3e1f8a51218827168cdclaireho 31535569331642446be05292e3e1f8a51218827168cdclaireho /* Note: The coverage table in format 2 doesn't give an index into 31545569331642446be05292e3e1f8a51218827168cdclaireho anything. It just lets us know whether or not we need to 31555569331642446be05292e3e1f8a51218827168cdclaireho do any lookup at all. */ 31565569331642446be05292e3e1f8a51218827168cdclaireho 31575569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &ccsf2->Coverage, IN_CURGLYPH(), &index ); 31585569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 31595569331642446be05292e3e1f8a51218827168cdclaireho return error; 31605569331642446be05292e3e1f8a51218827168cdclaireho 3161d124f9692dc8dad8f5f77c293fe6d4ec1a0c02eaRaph Levien if (ccsf2->MaxInputLength < 1) 3162d124f9692dc8dad8f5f77c293fe6d4ec1a0c02eaRaph Levien return HB_Err_Not_Covered; 3163d124f9692dc8dad8f5f77c293fe6d4ec1a0c02eaRaph Levien 31645569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( backtrack_classes, ccsf2->MaxBacktrackLength, HB_UShort ) ) 31655569331642446be05292e3e1f8a51218827168cdclaireho return error; 31665569331642446be05292e3e1f8a51218827168cdclaireho known_backtrack_classes = 0; 31675569331642446be05292e3e1f8a51218827168cdclaireho 31685569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( input_classes, ccsf2->MaxInputLength, HB_UShort ) ) 31695569331642446be05292e3e1f8a51218827168cdclaireho goto End3; 31705569331642446be05292e3e1f8a51218827168cdclaireho known_input_classes = 1; 31715569331642446be05292e3e1f8a51218827168cdclaireho 31725569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( lookahead_classes, ccsf2->MaxLookaheadLength, HB_UShort ) ) 31735569331642446be05292e3e1f8a51218827168cdclaireho goto End2; 31745569331642446be05292e3e1f8a51218827168cdclaireho known_lookahead_classes = 0; 31755569331642446be05292e3e1f8a51218827168cdclaireho 31765569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Get_Class( &ccsf2->InputClassDef, IN_CURGLYPH(), 31775569331642446be05292e3e1f8a51218827168cdclaireho &input_classes[0], NULL ); 31785569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 31795569331642446be05292e3e1f8a51218827168cdclaireho goto End1; 31805569331642446be05292e3e1f8a51218827168cdclaireho 31815569331642446be05292e3e1f8a51218827168cdclaireho cscs = &ccsf2->ChainSubClassSet[input_classes[0]]; 31825569331642446be05292e3e1f8a51218827168cdclaireho if ( !cscs ) 31835569331642446be05292e3e1f8a51218827168cdclaireho { 31845569331642446be05292e3e1f8a51218827168cdclaireho error = ERR(HB_Err_Invalid_SubTable); 31855569331642446be05292e3e1f8a51218827168cdclaireho goto End1; 31865569331642446be05292e3e1f8a51218827168cdclaireho } 31875569331642446be05292e3e1f8a51218827168cdclaireho 31885569331642446be05292e3e1f8a51218827168cdclaireho for ( k = 0; k < cscs->ChainSubClassRuleCount; k++ ) 31895569331642446be05292e3e1f8a51218827168cdclaireho { 31905569331642446be05292e3e1f8a51218827168cdclaireho ccsr = cscs->ChainSubClassRule[k]; 31915569331642446be05292e3e1f8a51218827168cdclaireho bgc = ccsr.BacktrackGlyphCount; 31925569331642446be05292e3e1f8a51218827168cdclaireho igc = ccsr.InputGlyphCount; 31935569331642446be05292e3e1f8a51218827168cdclaireho lgc = ccsr.LookaheadGlyphCount; 31945569331642446be05292e3e1f8a51218827168cdclaireho 31955569331642446be05292e3e1f8a51218827168cdclaireho if ( context_length != 0xFFFF && context_length < igc ) 31965569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainsubclassrule; 31975569331642446be05292e3e1f8a51218827168cdclaireho 31985569331642446be05292e3e1f8a51218827168cdclaireho /* check whether context is too long; it is a first guess only */ 31995569331642446be05292e3e1f8a51218827168cdclaireho 32005569331642446be05292e3e1f8a51218827168cdclaireho if ( bgc > buffer->out_pos || buffer->in_pos + igc + lgc > buffer->in_length ) 32015569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainsubclassrule; 32025569331642446be05292e3e1f8a51218827168cdclaireho 32035569331642446be05292e3e1f8a51218827168cdclaireho if ( bgc ) 32045569331642446be05292e3e1f8a51218827168cdclaireho { 32055569331642446be05292e3e1f8a51218827168cdclaireho /* Since we don't know in advance the number of glyphs to inspect, 32065569331642446be05292e3e1f8a51218827168cdclaireho we search backwards for matches in the backtrack glyph array. 32075569331642446be05292e3e1f8a51218827168cdclaireho Note that `known_backtrack_classes' starts at index 0. */ 32085569331642446be05292e3e1f8a51218827168cdclaireho 32095569331642446be05292e3e1f8a51218827168cdclaireho bc = ccsr.Backtrack; 32105569331642446be05292e3e1f8a51218827168cdclaireho 32115569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 0, j = buffer->out_pos - 1; i < bgc; i++, j-- ) 32125569331642446be05292e3e1f8a51218827168cdclaireho { 32135569331642446be05292e3e1f8a51218827168cdclaireho while ( CHECK_Property( gdef, OUT_ITEM( j ), flags, &property ) ) 32145569331642446be05292e3e1f8a51218827168cdclaireho { 32155569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 32165569331642446be05292e3e1f8a51218827168cdclaireho goto End1; 32175569331642446be05292e3e1f8a51218827168cdclaireho 32185569331642446be05292e3e1f8a51218827168cdclaireho if ( j + 1 == bgc - i ) 32195569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainsubclassrule; 32205569331642446be05292e3e1f8a51218827168cdclaireho j--; 32215569331642446be05292e3e1f8a51218827168cdclaireho } 32225569331642446be05292e3e1f8a51218827168cdclaireho 32235569331642446be05292e3e1f8a51218827168cdclaireho if ( i >= known_backtrack_classes ) 32245569331642446be05292e3e1f8a51218827168cdclaireho { 32255569331642446be05292e3e1f8a51218827168cdclaireho /* Keeps us from having to do this for each rule */ 32265569331642446be05292e3e1f8a51218827168cdclaireho 32275569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Get_Class( &ccsf2->BacktrackClassDef, OUT_GLYPH( j ), 32285569331642446be05292e3e1f8a51218827168cdclaireho &backtrack_classes[i], NULL ); 32295569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 32305569331642446be05292e3e1f8a51218827168cdclaireho goto End1; 32315569331642446be05292e3e1f8a51218827168cdclaireho known_backtrack_classes = i; 32325569331642446be05292e3e1f8a51218827168cdclaireho } 32335569331642446be05292e3e1f8a51218827168cdclaireho 32345569331642446be05292e3e1f8a51218827168cdclaireho if ( bc[i] != backtrack_classes[i] ) 32355569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainsubclassrule; 32365569331642446be05292e3e1f8a51218827168cdclaireho } 32375569331642446be05292e3e1f8a51218827168cdclaireho } 32385569331642446be05292e3e1f8a51218827168cdclaireho 32395569331642446be05292e3e1f8a51218827168cdclaireho ic = ccsr.Input; 32405569331642446be05292e3e1f8a51218827168cdclaireho 32415569331642446be05292e3e1f8a51218827168cdclaireho /* Start at 1 because [0] is implied */ 32425569331642446be05292e3e1f8a51218827168cdclaireho 32435569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 1, j = buffer->in_pos + 1; i < igc; i++, j++ ) 32445569331642446be05292e3e1f8a51218827168cdclaireho { 32455569331642446be05292e3e1f8a51218827168cdclaireho while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) 32465569331642446be05292e3e1f8a51218827168cdclaireho { 32475569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 32485569331642446be05292e3e1f8a51218827168cdclaireho goto End1; 32495569331642446be05292e3e1f8a51218827168cdclaireho 32505569331642446be05292e3e1f8a51218827168cdclaireho if ( j + igc - i + lgc == (HB_Int)buffer->in_length ) 32515569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainsubclassrule; 32525569331642446be05292e3e1f8a51218827168cdclaireho j++; 32535569331642446be05292e3e1f8a51218827168cdclaireho } 32545569331642446be05292e3e1f8a51218827168cdclaireho 32555569331642446be05292e3e1f8a51218827168cdclaireho if ( i >= known_input_classes ) 32565569331642446be05292e3e1f8a51218827168cdclaireho { 32575569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Get_Class( &ccsf2->InputClassDef, IN_GLYPH( j ), 32585569331642446be05292e3e1f8a51218827168cdclaireho &input_classes[i], NULL ); 32595569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 32605569331642446be05292e3e1f8a51218827168cdclaireho goto End1; 32615569331642446be05292e3e1f8a51218827168cdclaireho known_input_classes = i; 32625569331642446be05292e3e1f8a51218827168cdclaireho } 32635569331642446be05292e3e1f8a51218827168cdclaireho 32645569331642446be05292e3e1f8a51218827168cdclaireho if ( ic[i - 1] != input_classes[i] ) 32655569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainsubclassrule; 32665569331642446be05292e3e1f8a51218827168cdclaireho } 32675569331642446be05292e3e1f8a51218827168cdclaireho 32685569331642446be05292e3e1f8a51218827168cdclaireho /* we are starting to check for lookahead glyphs right after the 32695569331642446be05292e3e1f8a51218827168cdclaireho last context glyph */ 32705569331642446be05292e3e1f8a51218827168cdclaireho 32715569331642446be05292e3e1f8a51218827168cdclaireho lc = ccsr.Lookahead; 32725569331642446be05292e3e1f8a51218827168cdclaireho 32735569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 0; i < lgc; i++, j++ ) 32745569331642446be05292e3e1f8a51218827168cdclaireho { 32755569331642446be05292e3e1f8a51218827168cdclaireho while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) 32765569331642446be05292e3e1f8a51218827168cdclaireho { 32775569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 32785569331642446be05292e3e1f8a51218827168cdclaireho goto End1; 32795569331642446be05292e3e1f8a51218827168cdclaireho 32805569331642446be05292e3e1f8a51218827168cdclaireho if ( j + lgc - i == (HB_Int)buffer->in_length ) 32815569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainsubclassrule; 32825569331642446be05292e3e1f8a51218827168cdclaireho j++; 32835569331642446be05292e3e1f8a51218827168cdclaireho } 32845569331642446be05292e3e1f8a51218827168cdclaireho 32855569331642446be05292e3e1f8a51218827168cdclaireho if ( i >= known_lookahead_classes ) 32865569331642446be05292e3e1f8a51218827168cdclaireho { 32875569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Get_Class( &ccsf2->LookaheadClassDef, IN_GLYPH( j ), 32885569331642446be05292e3e1f8a51218827168cdclaireho &lookahead_classes[i], NULL ); 32895569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 32905569331642446be05292e3e1f8a51218827168cdclaireho goto End1; 32915569331642446be05292e3e1f8a51218827168cdclaireho known_lookahead_classes = i; 32925569331642446be05292e3e1f8a51218827168cdclaireho } 32935569331642446be05292e3e1f8a51218827168cdclaireho 32945569331642446be05292e3e1f8a51218827168cdclaireho if ( lc[i] != lookahead_classes[i] ) 32955569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainsubclassrule; 32965569331642446be05292e3e1f8a51218827168cdclaireho } 32975569331642446be05292e3e1f8a51218827168cdclaireho 32985569331642446be05292e3e1f8a51218827168cdclaireho error = Do_ContextSubst( gsub, igc, 32995569331642446be05292e3e1f8a51218827168cdclaireho ccsr.SubstCount, 33005569331642446be05292e3e1f8a51218827168cdclaireho ccsr.SubstLookupRecord, 33015569331642446be05292e3e1f8a51218827168cdclaireho buffer, 33025569331642446be05292e3e1f8a51218827168cdclaireho nesting_level ); 33035569331642446be05292e3e1f8a51218827168cdclaireho goto End1; 33045569331642446be05292e3e1f8a51218827168cdclaireho 33055569331642446be05292e3e1f8a51218827168cdclaireho next_chainsubclassrule: 33065569331642446be05292e3e1f8a51218827168cdclaireho ; 33075569331642446be05292e3e1f8a51218827168cdclaireho } 33085569331642446be05292e3e1f8a51218827168cdclaireho 33095569331642446be05292e3e1f8a51218827168cdclaireho error = HB_Err_Not_Covered; 33105569331642446be05292e3e1f8a51218827168cdclaireho 33115569331642446be05292e3e1f8a51218827168cdclairehoEnd1: 33125569331642446be05292e3e1f8a51218827168cdclaireho FREE( lookahead_classes ); 33135569331642446be05292e3e1f8a51218827168cdclaireho 33145569331642446be05292e3e1f8a51218827168cdclairehoEnd2: 33155569331642446be05292e3e1f8a51218827168cdclaireho FREE( input_classes ); 33165569331642446be05292e3e1f8a51218827168cdclaireho 33175569331642446be05292e3e1f8a51218827168cdclairehoEnd3: 33185569331642446be05292e3e1f8a51218827168cdclaireho FREE( backtrack_classes ); 33195569331642446be05292e3e1f8a51218827168cdclaireho return error; 33205569331642446be05292e3e1f8a51218827168cdclaireho} 33215569331642446be05292e3e1f8a51218827168cdclaireho 33225569331642446be05292e3e1f8a51218827168cdclaireho 33235569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Lookup_ChainContextSubst3( HB_GSUBHeader* gsub, 33245569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainContextSubstFormat3* ccsf3, 33255569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 33265569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort flags, 33275569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 33285569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 33295569331642446be05292e3e1f8a51218827168cdclaireho{ 33305569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort index, i, j, property; 33315569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort bgc, igc, lgc; 33325569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 33335569331642446be05292e3e1f8a51218827168cdclaireho 33345569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage* bc; 33355569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage* ic; 33365569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage* lc; 33375569331642446be05292e3e1f8a51218827168cdclaireho HB_GDEFHeader* gdef; 33385569331642446be05292e3e1f8a51218827168cdclaireho 33395569331642446be05292e3e1f8a51218827168cdclaireho 33405569331642446be05292e3e1f8a51218827168cdclaireho gdef = gsub->gdef; 33415569331642446be05292e3e1f8a51218827168cdclaireho 33425569331642446be05292e3e1f8a51218827168cdclaireho if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) 33435569331642446be05292e3e1f8a51218827168cdclaireho return error; 33445569331642446be05292e3e1f8a51218827168cdclaireho 33455569331642446be05292e3e1f8a51218827168cdclaireho bgc = ccsf3->BacktrackGlyphCount; 33465569331642446be05292e3e1f8a51218827168cdclaireho igc = ccsf3->InputGlyphCount; 33475569331642446be05292e3e1f8a51218827168cdclaireho lgc = ccsf3->LookaheadGlyphCount; 33485569331642446be05292e3e1f8a51218827168cdclaireho 33495569331642446be05292e3e1f8a51218827168cdclaireho if ( context_length != 0xFFFF && context_length < igc ) 33505569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 33515569331642446be05292e3e1f8a51218827168cdclaireho 33525569331642446be05292e3e1f8a51218827168cdclaireho /* check whether context is too long; it is a first guess only */ 33535569331642446be05292e3e1f8a51218827168cdclaireho 33545569331642446be05292e3e1f8a51218827168cdclaireho if ( bgc > buffer->out_pos || buffer->in_pos + igc + lgc > buffer->in_length ) 33555569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 33565569331642446be05292e3e1f8a51218827168cdclaireho 33575569331642446be05292e3e1f8a51218827168cdclaireho if ( bgc ) 33585569331642446be05292e3e1f8a51218827168cdclaireho { 33595569331642446be05292e3e1f8a51218827168cdclaireho /* Since we don't know in advance the number of glyphs to inspect, 33605569331642446be05292e3e1f8a51218827168cdclaireho we search backwards for matches in the backtrack glyph array */ 33615569331642446be05292e3e1f8a51218827168cdclaireho 33625569331642446be05292e3e1f8a51218827168cdclaireho bc = ccsf3->BacktrackCoverage; 33635569331642446be05292e3e1f8a51218827168cdclaireho 33645569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 0, j = buffer->out_pos - 1; i < bgc; i++, j-- ) 33655569331642446be05292e3e1f8a51218827168cdclaireho { 33665569331642446be05292e3e1f8a51218827168cdclaireho while ( CHECK_Property( gdef, OUT_ITEM( j ), flags, &property ) ) 33675569331642446be05292e3e1f8a51218827168cdclaireho { 33685569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 33695569331642446be05292e3e1f8a51218827168cdclaireho return error; 33705569331642446be05292e3e1f8a51218827168cdclaireho 33715569331642446be05292e3e1f8a51218827168cdclaireho if ( j + 1 == bgc - i ) 33725569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 33735569331642446be05292e3e1f8a51218827168cdclaireho j--; 33745569331642446be05292e3e1f8a51218827168cdclaireho } 33755569331642446be05292e3e1f8a51218827168cdclaireho 33765569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &bc[i], OUT_GLYPH( j ), &index ); 33775569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 33785569331642446be05292e3e1f8a51218827168cdclaireho return error; 33795569331642446be05292e3e1f8a51218827168cdclaireho } 33805569331642446be05292e3e1f8a51218827168cdclaireho } 33815569331642446be05292e3e1f8a51218827168cdclaireho 33825569331642446be05292e3e1f8a51218827168cdclaireho ic = ccsf3->InputCoverage; 33835569331642446be05292e3e1f8a51218827168cdclaireho 33845569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 0, j = buffer->in_pos; i < igc; i++, j++ ) 33855569331642446be05292e3e1f8a51218827168cdclaireho { 33865569331642446be05292e3e1f8a51218827168cdclaireho /* We already called CHECK_Property for IN_GLYPH( buffer->in_pos ) */ 33875569331642446be05292e3e1f8a51218827168cdclaireho while ( j > buffer->in_pos && CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) 33885569331642446be05292e3e1f8a51218827168cdclaireho { 33895569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 33905569331642446be05292e3e1f8a51218827168cdclaireho return error; 33915569331642446be05292e3e1f8a51218827168cdclaireho 33925569331642446be05292e3e1f8a51218827168cdclaireho if ( j + igc - i + lgc == (HB_Int)buffer->in_length ) 33935569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 33945569331642446be05292e3e1f8a51218827168cdclaireho j++; 33955569331642446be05292e3e1f8a51218827168cdclaireho } 33965569331642446be05292e3e1f8a51218827168cdclaireho 33975569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &ic[i], IN_GLYPH( j ), &index ); 33985569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 33995569331642446be05292e3e1f8a51218827168cdclaireho return error; 34005569331642446be05292e3e1f8a51218827168cdclaireho } 34015569331642446be05292e3e1f8a51218827168cdclaireho 34025569331642446be05292e3e1f8a51218827168cdclaireho /* we are starting for lookahead glyphs right after the last context 34035569331642446be05292e3e1f8a51218827168cdclaireho glyph */ 34045569331642446be05292e3e1f8a51218827168cdclaireho 34055569331642446be05292e3e1f8a51218827168cdclaireho lc = ccsf3->LookaheadCoverage; 34065569331642446be05292e3e1f8a51218827168cdclaireho 34075569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 0; i < lgc; i++, j++ ) 34085569331642446be05292e3e1f8a51218827168cdclaireho { 34095569331642446be05292e3e1f8a51218827168cdclaireho while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) 34105569331642446be05292e3e1f8a51218827168cdclaireho { 34115569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 34125569331642446be05292e3e1f8a51218827168cdclaireho return error; 34135569331642446be05292e3e1f8a51218827168cdclaireho 34145569331642446be05292e3e1f8a51218827168cdclaireho if ( j + lgc - i == (HB_Int)buffer->in_length ) 34155569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 34165569331642446be05292e3e1f8a51218827168cdclaireho j++; 34175569331642446be05292e3e1f8a51218827168cdclaireho } 34185569331642446be05292e3e1f8a51218827168cdclaireho 34195569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &lc[i], IN_GLYPH( j ), &index ); 34205569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 34215569331642446be05292e3e1f8a51218827168cdclaireho return error; 34225569331642446be05292e3e1f8a51218827168cdclaireho } 34235569331642446be05292e3e1f8a51218827168cdclaireho 34245569331642446be05292e3e1f8a51218827168cdclaireho return Do_ContextSubst( gsub, igc, 34255569331642446be05292e3e1f8a51218827168cdclaireho ccsf3->SubstCount, 34265569331642446be05292e3e1f8a51218827168cdclaireho ccsf3->SubstLookupRecord, 34275569331642446be05292e3e1f8a51218827168cdclaireho buffer, 34285569331642446be05292e3e1f8a51218827168cdclaireho nesting_level ); 34295569331642446be05292e3e1f8a51218827168cdclaireho} 34305569331642446be05292e3e1f8a51218827168cdclaireho 34315569331642446be05292e3e1f8a51218827168cdclaireho 34325569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Lookup_ChainContextSubst( HB_GSUBHeader* gsub, 34335569331642446be05292e3e1f8a51218827168cdclaireho HB_GSUB_SubTable* st, 34345569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 34355569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort flags, 34365569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 34375569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 34385569331642446be05292e3e1f8a51218827168cdclaireho{ 34395569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainContextSubst* ccs = &st->chain; 34405569331642446be05292e3e1f8a51218827168cdclaireho 34415569331642446be05292e3e1f8a51218827168cdclaireho switch ( ccs->SubstFormat ) { 34425569331642446be05292e3e1f8a51218827168cdclaireho case 1: return Lookup_ChainContextSubst1( gsub, &ccs->ccsf.ccsf1, buffer, flags, context_length, nesting_level ); 34435569331642446be05292e3e1f8a51218827168cdclaireho case 2: return Lookup_ChainContextSubst2( gsub, &ccs->ccsf.ccsf2, buffer, flags, context_length, nesting_level ); 34445569331642446be05292e3e1f8a51218827168cdclaireho case 3: return Lookup_ChainContextSubst3( gsub, &ccs->ccsf.ccsf3, buffer, flags, context_length, nesting_level ); 34455569331642446be05292e3e1f8a51218827168cdclaireho default: return ERR(HB_Err_Invalid_SubTable_Format); 34465569331642446be05292e3e1f8a51218827168cdclaireho } 34475569331642446be05292e3e1f8a51218827168cdclaireho} 34485569331642446be05292e3e1f8a51218827168cdclaireho 34495569331642446be05292e3e1f8a51218827168cdclaireho 34505569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_ReverseChainContextSubst( HB_GSUB_SubTable* st, 34515569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 34525569331642446be05292e3e1f8a51218827168cdclaireho{ 34535569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 34545569331642446be05292e3e1f8a51218827168cdclaireho HB_ReverseChainContextSubst* rccs = &st->reverse; 34555569331642446be05292e3e1f8a51218827168cdclaireho 34565569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort m, count; 34575569331642446be05292e3e1f8a51218827168cdclaireho 34585569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort nb = 0, nl = 0, n; 34595569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort backtrack_count, lookahead_count; 34605569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 34615569331642446be05292e3e1f8a51218827168cdclaireho 34625569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage* b; 34635569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage* l; 34645569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* sub; 34655569331642446be05292e3e1f8a51218827168cdclaireho 34665569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 34675569331642446be05292e3e1f8a51218827168cdclaireho 34685569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 34695569331642446be05292e3e1f8a51218827168cdclaireho return error; 34705569331642446be05292e3e1f8a51218827168cdclaireho 34715569331642446be05292e3e1f8a51218827168cdclaireho rccs->SubstFormat = GET_UShort(); 34725569331642446be05292e3e1f8a51218827168cdclaireho 34735569331642446be05292e3e1f8a51218827168cdclaireho if ( rccs->SubstFormat != 1 ) 34745569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable_Format); 34755569331642446be05292e3e1f8a51218827168cdclaireho 34765569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 34775569331642446be05292e3e1f8a51218827168cdclaireho 34785569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 34795569331642446be05292e3e1f8a51218827168cdclaireho return error; 34805569331642446be05292e3e1f8a51218827168cdclaireho 34815569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 34825569331642446be05292e3e1f8a51218827168cdclaireho 34835569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 34845569331642446be05292e3e1f8a51218827168cdclaireho 34855569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 34865569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 34875569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &rccs->Coverage, stream ) ) != HB_Err_Ok ) 34885569331642446be05292e3e1f8a51218827168cdclaireho return error; 34895569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 34905569331642446be05292e3e1f8a51218827168cdclaireho 34915569331642446be05292e3e1f8a51218827168cdclaireho 34925569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 34935569331642446be05292e3e1f8a51218827168cdclaireho goto Fail4; 34945569331642446be05292e3e1f8a51218827168cdclaireho 34955569331642446be05292e3e1f8a51218827168cdclaireho rccs->BacktrackGlyphCount = GET_UShort(); 34965569331642446be05292e3e1f8a51218827168cdclaireho 34975569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 34985569331642446be05292e3e1f8a51218827168cdclaireho 34995569331642446be05292e3e1f8a51218827168cdclaireho rccs->BacktrackCoverage = NULL; 35005569331642446be05292e3e1f8a51218827168cdclaireho 35015569331642446be05292e3e1f8a51218827168cdclaireho backtrack_count = rccs->BacktrackGlyphCount; 35025569331642446be05292e3e1f8a51218827168cdclaireho 35035569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( rccs->BacktrackCoverage, backtrack_count, 35045569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage ) ) 35055569331642446be05292e3e1f8a51218827168cdclaireho goto Fail4; 35065569331642446be05292e3e1f8a51218827168cdclaireho 35075569331642446be05292e3e1f8a51218827168cdclaireho b = rccs->BacktrackCoverage; 35085569331642446be05292e3e1f8a51218827168cdclaireho 35095569331642446be05292e3e1f8a51218827168cdclaireho for ( nb = 0; nb < backtrack_count; nb++ ) 35105569331642446be05292e3e1f8a51218827168cdclaireho { 35115569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 35125569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 35135569331642446be05292e3e1f8a51218827168cdclaireho 35145569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 35155569331642446be05292e3e1f8a51218827168cdclaireho 35165569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 35175569331642446be05292e3e1f8a51218827168cdclaireho 35185569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 35195569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 35205569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &b[nb], stream ) ) != HB_Err_Ok ) 35215569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 35225569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 35235569331642446be05292e3e1f8a51218827168cdclaireho } 35245569331642446be05292e3e1f8a51218827168cdclaireho 35255569331642446be05292e3e1f8a51218827168cdclaireho 35265569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 35275569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 35285569331642446be05292e3e1f8a51218827168cdclaireho 35295569331642446be05292e3e1f8a51218827168cdclaireho rccs->LookaheadGlyphCount = GET_UShort(); 35305569331642446be05292e3e1f8a51218827168cdclaireho 35315569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 35325569331642446be05292e3e1f8a51218827168cdclaireho 35335569331642446be05292e3e1f8a51218827168cdclaireho rccs->LookaheadCoverage = NULL; 35345569331642446be05292e3e1f8a51218827168cdclaireho 35355569331642446be05292e3e1f8a51218827168cdclaireho lookahead_count = rccs->LookaheadGlyphCount; 35365569331642446be05292e3e1f8a51218827168cdclaireho 35375569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( rccs->LookaheadCoverage, lookahead_count, 35385569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage ) ) 35395569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 35405569331642446be05292e3e1f8a51218827168cdclaireho 35415569331642446be05292e3e1f8a51218827168cdclaireho l = rccs->LookaheadCoverage; 35425569331642446be05292e3e1f8a51218827168cdclaireho 35435569331642446be05292e3e1f8a51218827168cdclaireho for ( nl = 0; nl < lookahead_count; nl++ ) 35445569331642446be05292e3e1f8a51218827168cdclaireho { 35455569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 35465569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 35475569331642446be05292e3e1f8a51218827168cdclaireho 35485569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 35495569331642446be05292e3e1f8a51218827168cdclaireho 35505569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 35515569331642446be05292e3e1f8a51218827168cdclaireho 35525569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 35535569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 35545569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &l[nl], stream ) ) != HB_Err_Ok ) 35555569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 35565569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 35575569331642446be05292e3e1f8a51218827168cdclaireho } 35585569331642446be05292e3e1f8a51218827168cdclaireho 35595569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 35605569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 35615569331642446be05292e3e1f8a51218827168cdclaireho 35625569331642446be05292e3e1f8a51218827168cdclaireho rccs->GlyphCount = GET_UShort(); 35635569331642446be05292e3e1f8a51218827168cdclaireho 35645569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 35655569331642446be05292e3e1f8a51218827168cdclaireho 35665569331642446be05292e3e1f8a51218827168cdclaireho rccs->Substitute = NULL; 35675569331642446be05292e3e1f8a51218827168cdclaireho 35685569331642446be05292e3e1f8a51218827168cdclaireho count = rccs->GlyphCount; 35695569331642446be05292e3e1f8a51218827168cdclaireho 35705569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( rccs->Substitute, count, 35715569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort ) ) 35725569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 35735569331642446be05292e3e1f8a51218827168cdclaireho 35745569331642446be05292e3e1f8a51218827168cdclaireho sub = rccs->Substitute; 35755569331642446be05292e3e1f8a51218827168cdclaireho 35765569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 2L ) ) 35775569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 35785569331642446be05292e3e1f8a51218827168cdclaireho 35795569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 35805569331642446be05292e3e1f8a51218827168cdclaireho sub[n] = GET_UShort(); 35815569331642446be05292e3e1f8a51218827168cdclaireho 35825569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 35835569331642446be05292e3e1f8a51218827168cdclaireho 35845569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 35855569331642446be05292e3e1f8a51218827168cdclaireho 35865569331642446be05292e3e1f8a51218827168cdclairehoFail1: 35875569331642446be05292e3e1f8a51218827168cdclaireho FREE( sub ); 35885569331642446be05292e3e1f8a51218827168cdclaireho 35895569331642446be05292e3e1f8a51218827168cdclairehoFail2: 35905569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < nl; m++ ) 35915569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &l[m] ); 35925569331642446be05292e3e1f8a51218827168cdclaireho 35935569331642446be05292e3e1f8a51218827168cdclaireho FREE( l ); 35945569331642446be05292e3e1f8a51218827168cdclaireho 35955569331642446be05292e3e1f8a51218827168cdclairehoFail3: 35965569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < nb; m++ ) 35975569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &b[m] ); 35985569331642446be05292e3e1f8a51218827168cdclaireho 35995569331642446be05292e3e1f8a51218827168cdclaireho FREE( b ); 36005569331642446be05292e3e1f8a51218827168cdclaireho 36015569331642446be05292e3e1f8a51218827168cdclairehoFail4: 36025569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &rccs->Coverage ); 36035569331642446be05292e3e1f8a51218827168cdclaireho return error; 36045569331642446be05292e3e1f8a51218827168cdclaireho} 36055569331642446be05292e3e1f8a51218827168cdclaireho 36065569331642446be05292e3e1f8a51218827168cdclaireho 36075569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_ReverseChainContextSubst( HB_GSUB_SubTable* st ) 36085569331642446be05292e3e1f8a51218827168cdclaireho{ 36095569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 36105569331642446be05292e3e1f8a51218827168cdclaireho HB_ReverseChainContextSubst* rccs = &st->reverse; 36115569331642446be05292e3e1f8a51218827168cdclaireho 36125569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage* c; 36135569331642446be05292e3e1f8a51218827168cdclaireho 36145569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &rccs->Coverage ); 36155569331642446be05292e3e1f8a51218827168cdclaireho 36165569331642446be05292e3e1f8a51218827168cdclaireho if ( rccs->LookaheadCoverage ) 36175569331642446be05292e3e1f8a51218827168cdclaireho { 36185569331642446be05292e3e1f8a51218827168cdclaireho count = rccs->LookaheadGlyphCount; 36195569331642446be05292e3e1f8a51218827168cdclaireho c = rccs->LookaheadCoverage; 36205569331642446be05292e3e1f8a51218827168cdclaireho 36215569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 36225569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &c[n] ); 36235569331642446be05292e3e1f8a51218827168cdclaireho 36245569331642446be05292e3e1f8a51218827168cdclaireho FREE( c ); 36255569331642446be05292e3e1f8a51218827168cdclaireho } 36265569331642446be05292e3e1f8a51218827168cdclaireho 36275569331642446be05292e3e1f8a51218827168cdclaireho if ( rccs->BacktrackCoverage ) 36285569331642446be05292e3e1f8a51218827168cdclaireho { 36295569331642446be05292e3e1f8a51218827168cdclaireho count = rccs->BacktrackGlyphCount; 36305569331642446be05292e3e1f8a51218827168cdclaireho c = rccs->BacktrackCoverage; 36315569331642446be05292e3e1f8a51218827168cdclaireho 36325569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 36335569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &c[n] ); 36345569331642446be05292e3e1f8a51218827168cdclaireho 36355569331642446be05292e3e1f8a51218827168cdclaireho FREE( c ); 36365569331642446be05292e3e1f8a51218827168cdclaireho } 36375569331642446be05292e3e1f8a51218827168cdclaireho 36385569331642446be05292e3e1f8a51218827168cdclaireho FREE ( rccs->Substitute ); 36395569331642446be05292e3e1f8a51218827168cdclaireho} 36405569331642446be05292e3e1f8a51218827168cdclaireho 36415569331642446be05292e3e1f8a51218827168cdclaireho 36425569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Lookup_ReverseChainContextSubst( HB_GSUBHeader* gsub, 36435569331642446be05292e3e1f8a51218827168cdclaireho HB_GSUB_SubTable* st, 36445569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 36455569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort flags, 36465569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 36475569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 36485569331642446be05292e3e1f8a51218827168cdclaireho{ 36495569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort index, input_index, i, j, property; 36505569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort bgc, lgc; 36515569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 36525569331642446be05292e3e1f8a51218827168cdclaireho 36535569331642446be05292e3e1f8a51218827168cdclaireho HB_ReverseChainContextSubst* rccs = &st->reverse; 36545569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage* bc; 36555569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage* lc; 36565569331642446be05292e3e1f8a51218827168cdclaireho HB_GDEFHeader* gdef; 36575569331642446be05292e3e1f8a51218827168cdclaireho 36585569331642446be05292e3e1f8a51218827168cdclaireho if ( nesting_level != 1 || context_length != 0xFFFF ) 36595569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 36605569331642446be05292e3e1f8a51218827168cdclaireho 36615569331642446be05292e3e1f8a51218827168cdclaireho gdef = gsub->gdef; 36625569331642446be05292e3e1f8a51218827168cdclaireho 36635569331642446be05292e3e1f8a51218827168cdclaireho if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) 36645569331642446be05292e3e1f8a51218827168cdclaireho return error; 36655569331642446be05292e3e1f8a51218827168cdclaireho 36665569331642446be05292e3e1f8a51218827168cdclaireho bgc = rccs->BacktrackGlyphCount; 36675569331642446be05292e3e1f8a51218827168cdclaireho lgc = rccs->LookaheadGlyphCount; 36685569331642446be05292e3e1f8a51218827168cdclaireho 36695569331642446be05292e3e1f8a51218827168cdclaireho /* check whether context is too long; it is a first guess only */ 36705569331642446be05292e3e1f8a51218827168cdclaireho 36715569331642446be05292e3e1f8a51218827168cdclaireho if ( bgc > buffer->in_pos || buffer->in_pos + 1 + lgc > buffer->in_length ) 36725569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 36735569331642446be05292e3e1f8a51218827168cdclaireho 36745569331642446be05292e3e1f8a51218827168cdclaireho if ( bgc ) 36755569331642446be05292e3e1f8a51218827168cdclaireho { 36765569331642446be05292e3e1f8a51218827168cdclaireho /* Since we don't know in advance the number of glyphs to inspect, 36775569331642446be05292e3e1f8a51218827168cdclaireho we search backwards for matches in the backtrack glyph array */ 36785569331642446be05292e3e1f8a51218827168cdclaireho 36795569331642446be05292e3e1f8a51218827168cdclaireho bc = rccs->BacktrackCoverage; 36805569331642446be05292e3e1f8a51218827168cdclaireho 36815569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 0, j = buffer->in_pos - 1; i < bgc; i++, j-- ) 36825569331642446be05292e3e1f8a51218827168cdclaireho { 36835569331642446be05292e3e1f8a51218827168cdclaireho while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) 36845569331642446be05292e3e1f8a51218827168cdclaireho { 36855569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 36865569331642446be05292e3e1f8a51218827168cdclaireho return error; 36875569331642446be05292e3e1f8a51218827168cdclaireho 36885569331642446be05292e3e1f8a51218827168cdclaireho if ( j + 1 == bgc - i ) 36895569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 36905569331642446be05292e3e1f8a51218827168cdclaireho j--; 36915569331642446be05292e3e1f8a51218827168cdclaireho } 36925569331642446be05292e3e1f8a51218827168cdclaireho 36935569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &bc[i], IN_GLYPH( j ), &index ); 36945569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 36955569331642446be05292e3e1f8a51218827168cdclaireho return error; 36965569331642446be05292e3e1f8a51218827168cdclaireho } 36975569331642446be05292e3e1f8a51218827168cdclaireho } 36985569331642446be05292e3e1f8a51218827168cdclaireho 36995569331642446be05292e3e1f8a51218827168cdclaireho j = buffer->in_pos; 37005569331642446be05292e3e1f8a51218827168cdclaireho 37015569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &rccs->Coverage, IN_GLYPH( j ), &input_index ); 37025569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 37035569331642446be05292e3e1f8a51218827168cdclaireho return error; 37045569331642446be05292e3e1f8a51218827168cdclaireho 37055569331642446be05292e3e1f8a51218827168cdclaireho lc = rccs->LookaheadCoverage; 37065569331642446be05292e3e1f8a51218827168cdclaireho 37075569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 0, j = buffer->in_pos + 1; i < lgc; i++, j++ ) 37085569331642446be05292e3e1f8a51218827168cdclaireho { 37095569331642446be05292e3e1f8a51218827168cdclaireho while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) 37105569331642446be05292e3e1f8a51218827168cdclaireho { 37115569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 37125569331642446be05292e3e1f8a51218827168cdclaireho return error; 37135569331642446be05292e3e1f8a51218827168cdclaireho 37145569331642446be05292e3e1f8a51218827168cdclaireho if ( j + lgc - i == (HB_Int)buffer->in_length ) 37155569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 37165569331642446be05292e3e1f8a51218827168cdclaireho j++; 37175569331642446be05292e3e1f8a51218827168cdclaireho } 37185569331642446be05292e3e1f8a51218827168cdclaireho 37195569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &lc[i], IN_GLYPH( j ), &index ); 37205569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 37215569331642446be05292e3e1f8a51218827168cdclaireho return error; 37225569331642446be05292e3e1f8a51218827168cdclaireho } 37235569331642446be05292e3e1f8a51218827168cdclaireho 37245569331642446be05292e3e1f8a51218827168cdclaireho IN_CURGLYPH() = rccs->Substitute[input_index]; 37255569331642446be05292e3e1f8a51218827168cdclaireho buffer->in_pos--; /* Reverse! */ 37265569331642446be05292e3e1f8a51218827168cdclaireho 37275569331642446be05292e3e1f8a51218827168cdclaireho return error; 37285569331642446be05292e3e1f8a51218827168cdclaireho} 37295569331642446be05292e3e1f8a51218827168cdclaireho 37305569331642446be05292e3e1f8a51218827168cdclaireho 37315569331642446be05292e3e1f8a51218827168cdclaireho 37325569331642446be05292e3e1f8a51218827168cdclaireho/*********** 37335569331642446be05292e3e1f8a51218827168cdclaireho * GSUB API 37345569331642446be05292e3e1f8a51218827168cdclaireho ***********/ 37355569331642446be05292e3e1f8a51218827168cdclaireho 37365569331642446be05292e3e1f8a51218827168cdclaireho 37375569331642446be05292e3e1f8a51218827168cdclaireho 37385569331642446be05292e3e1f8a51218827168cdclairehoHB_Error HB_GSUB_Select_Script( HB_GSUBHeader* gsub, 37395569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt script_tag, 37405569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* script_index ) 37415569331642446be05292e3e1f8a51218827168cdclaireho{ 37425569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n; 37435569331642446be05292e3e1f8a51218827168cdclaireho 37445569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptList* sl; 37455569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptRecord* sr; 37465569331642446be05292e3e1f8a51218827168cdclaireho 37475569331642446be05292e3e1f8a51218827168cdclaireho 37485569331642446be05292e3e1f8a51218827168cdclaireho if ( !gsub || !script_index ) 37495569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 37505569331642446be05292e3e1f8a51218827168cdclaireho 37515569331642446be05292e3e1f8a51218827168cdclaireho sl = &gsub->ScriptList; 37525569331642446be05292e3e1f8a51218827168cdclaireho sr = sl->ScriptRecord; 37535569331642446be05292e3e1f8a51218827168cdclaireho 37545569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < sl->ScriptCount; n++ ) 37555569331642446be05292e3e1f8a51218827168cdclaireho if ( script_tag == sr[n].ScriptTag ) 37565569331642446be05292e3e1f8a51218827168cdclaireho { 37575569331642446be05292e3e1f8a51218827168cdclaireho *script_index = n; 37585569331642446be05292e3e1f8a51218827168cdclaireho 37595569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 37605569331642446be05292e3e1f8a51218827168cdclaireho } 37615569331642446be05292e3e1f8a51218827168cdclaireho 37625569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 37635569331642446be05292e3e1f8a51218827168cdclaireho} 37645569331642446be05292e3e1f8a51218827168cdclaireho 37655569331642446be05292e3e1f8a51218827168cdclaireho 37665569331642446be05292e3e1f8a51218827168cdclaireho 37675569331642446be05292e3e1f8a51218827168cdclairehoHB_Error HB_GSUB_Select_Language( HB_GSUBHeader* gsub, 37685569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt language_tag, 37695569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort script_index, 37705569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* language_index, 37715569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* req_feature_index ) 37725569331642446be05292e3e1f8a51218827168cdclaireho{ 37735569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n; 37745569331642446be05292e3e1f8a51218827168cdclaireho 37755569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptList* sl; 37765569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptRecord* sr; 37775569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptTable* s; 37785569331642446be05292e3e1f8a51218827168cdclaireho HB_LangSysRecord* lsr; 37795569331642446be05292e3e1f8a51218827168cdclaireho 37805569331642446be05292e3e1f8a51218827168cdclaireho 37815569331642446be05292e3e1f8a51218827168cdclaireho if ( !gsub || !language_index || !req_feature_index ) 37825569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 37835569331642446be05292e3e1f8a51218827168cdclaireho 37845569331642446be05292e3e1f8a51218827168cdclaireho sl = &gsub->ScriptList; 37855569331642446be05292e3e1f8a51218827168cdclaireho sr = sl->ScriptRecord; 37865569331642446be05292e3e1f8a51218827168cdclaireho 37875569331642446be05292e3e1f8a51218827168cdclaireho if ( script_index >= sl->ScriptCount ) 37885569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 37895569331642446be05292e3e1f8a51218827168cdclaireho 37905569331642446be05292e3e1f8a51218827168cdclaireho s = &sr[script_index].Script; 37915569331642446be05292e3e1f8a51218827168cdclaireho lsr = s->LangSysRecord; 37925569331642446be05292e3e1f8a51218827168cdclaireho 37935569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < s->LangSysCount; n++ ) 37945569331642446be05292e3e1f8a51218827168cdclaireho if ( language_tag == lsr[n].LangSysTag ) 37955569331642446be05292e3e1f8a51218827168cdclaireho { 37965569331642446be05292e3e1f8a51218827168cdclaireho *language_index = n; 37975569331642446be05292e3e1f8a51218827168cdclaireho *req_feature_index = lsr[n].LangSys.ReqFeatureIndex; 37985569331642446be05292e3e1f8a51218827168cdclaireho 37995569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 38005569331642446be05292e3e1f8a51218827168cdclaireho } 38015569331642446be05292e3e1f8a51218827168cdclaireho 38025569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 38035569331642446be05292e3e1f8a51218827168cdclaireho} 38045569331642446be05292e3e1f8a51218827168cdclaireho 38055569331642446be05292e3e1f8a51218827168cdclaireho 38065569331642446be05292e3e1f8a51218827168cdclaireho/* selecting 0xFFFF for language_index asks for the values of the 38075569331642446be05292e3e1f8a51218827168cdclaireho default language (DefaultLangSys) */ 38085569331642446be05292e3e1f8a51218827168cdclaireho 38095569331642446be05292e3e1f8a51218827168cdclaireho 38105569331642446be05292e3e1f8a51218827168cdclairehoHB_Error HB_GSUB_Select_Feature( HB_GSUBHeader* gsub, 38115569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt feature_tag, 38125569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort script_index, 38135569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort language_index, 38145569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* feature_index ) 38155569331642446be05292e3e1f8a51218827168cdclaireho{ 38165569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n; 38175569331642446be05292e3e1f8a51218827168cdclaireho 38185569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptList* sl; 38195569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptRecord* sr; 38205569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptTable* s; 38215569331642446be05292e3e1f8a51218827168cdclaireho HB_LangSysRecord* lsr; 38225569331642446be05292e3e1f8a51218827168cdclaireho HB_LangSys* ls; 38235569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* fi; 38245569331642446be05292e3e1f8a51218827168cdclaireho 38255569331642446be05292e3e1f8a51218827168cdclaireho HB_FeatureList* fl; 38265569331642446be05292e3e1f8a51218827168cdclaireho HB_FeatureRecord* fr; 38275569331642446be05292e3e1f8a51218827168cdclaireho 38285569331642446be05292e3e1f8a51218827168cdclaireho 38295569331642446be05292e3e1f8a51218827168cdclaireho if ( !gsub || !feature_index ) 38305569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 38315569331642446be05292e3e1f8a51218827168cdclaireho 38325569331642446be05292e3e1f8a51218827168cdclaireho sl = &gsub->ScriptList; 38335569331642446be05292e3e1f8a51218827168cdclaireho sr = sl->ScriptRecord; 38345569331642446be05292e3e1f8a51218827168cdclaireho 38355569331642446be05292e3e1f8a51218827168cdclaireho fl = &gsub->FeatureList; 38365569331642446be05292e3e1f8a51218827168cdclaireho fr = fl->FeatureRecord; 38375569331642446be05292e3e1f8a51218827168cdclaireho 38385569331642446be05292e3e1f8a51218827168cdclaireho if ( script_index >= sl->ScriptCount ) 38395569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 38405569331642446be05292e3e1f8a51218827168cdclaireho 38415569331642446be05292e3e1f8a51218827168cdclaireho s = &sr[script_index].Script; 38425569331642446be05292e3e1f8a51218827168cdclaireho lsr = s->LangSysRecord; 38435569331642446be05292e3e1f8a51218827168cdclaireho 38445569331642446be05292e3e1f8a51218827168cdclaireho if ( language_index == 0xFFFF ) 38455569331642446be05292e3e1f8a51218827168cdclaireho ls = &s->DefaultLangSys; 38465569331642446be05292e3e1f8a51218827168cdclaireho else 38475569331642446be05292e3e1f8a51218827168cdclaireho { 38485569331642446be05292e3e1f8a51218827168cdclaireho if ( language_index >= s->LangSysCount ) 38495569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 38505569331642446be05292e3e1f8a51218827168cdclaireho 38515569331642446be05292e3e1f8a51218827168cdclaireho ls = &lsr[language_index].LangSys; 38525569331642446be05292e3e1f8a51218827168cdclaireho } 38535569331642446be05292e3e1f8a51218827168cdclaireho 38545569331642446be05292e3e1f8a51218827168cdclaireho fi = ls->FeatureIndex; 38555569331642446be05292e3e1f8a51218827168cdclaireho 38565569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < ls->FeatureCount; n++ ) 38575569331642446be05292e3e1f8a51218827168cdclaireho { 38585569331642446be05292e3e1f8a51218827168cdclaireho if ( fi[n] >= fl->FeatureCount ) 38595569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable_Format); 38605569331642446be05292e3e1f8a51218827168cdclaireho 38615569331642446be05292e3e1f8a51218827168cdclaireho if ( feature_tag == fr[fi[n]].FeatureTag ) 38625569331642446be05292e3e1f8a51218827168cdclaireho { 38635569331642446be05292e3e1f8a51218827168cdclaireho *feature_index = fi[n]; 38645569331642446be05292e3e1f8a51218827168cdclaireho 38655569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 38665569331642446be05292e3e1f8a51218827168cdclaireho } 38675569331642446be05292e3e1f8a51218827168cdclaireho } 38685569331642446be05292e3e1f8a51218827168cdclaireho 38695569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 38705569331642446be05292e3e1f8a51218827168cdclaireho} 38715569331642446be05292e3e1f8a51218827168cdclaireho 38725569331642446be05292e3e1f8a51218827168cdclaireho 38735569331642446be05292e3e1f8a51218827168cdclaireho/* The next three functions return a null-terminated list */ 38745569331642446be05292e3e1f8a51218827168cdclaireho 38755569331642446be05292e3e1f8a51218827168cdclaireho 38765569331642446be05292e3e1f8a51218827168cdclairehoHB_Error HB_GSUB_Query_Scripts( HB_GSUBHeader* gsub, 38775569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt** script_tag_list ) 38785569331642446be05292e3e1f8a51218827168cdclaireho{ 38795569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n; 38805569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 38815569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt* stl; 38825569331642446be05292e3e1f8a51218827168cdclaireho 38835569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptList* sl; 38845569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptRecord* sr; 38855569331642446be05292e3e1f8a51218827168cdclaireho 38865569331642446be05292e3e1f8a51218827168cdclaireho 38875569331642446be05292e3e1f8a51218827168cdclaireho if ( !gsub || !script_tag_list ) 38885569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 38895569331642446be05292e3e1f8a51218827168cdclaireho 38905569331642446be05292e3e1f8a51218827168cdclaireho sl = &gsub->ScriptList; 38915569331642446be05292e3e1f8a51218827168cdclaireho sr = sl->ScriptRecord; 38925569331642446be05292e3e1f8a51218827168cdclaireho 38935569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( stl, sl->ScriptCount + 1, HB_UInt ) ) 38945569331642446be05292e3e1f8a51218827168cdclaireho return error; 38955569331642446be05292e3e1f8a51218827168cdclaireho 38965569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < sl->ScriptCount; n++ ) 38975569331642446be05292e3e1f8a51218827168cdclaireho stl[n] = sr[n].ScriptTag; 38985569331642446be05292e3e1f8a51218827168cdclaireho stl[n] = 0; 38995569331642446be05292e3e1f8a51218827168cdclaireho 39005569331642446be05292e3e1f8a51218827168cdclaireho *script_tag_list = stl; 39015569331642446be05292e3e1f8a51218827168cdclaireho 39025569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 39035569331642446be05292e3e1f8a51218827168cdclaireho} 39045569331642446be05292e3e1f8a51218827168cdclaireho 39055569331642446be05292e3e1f8a51218827168cdclaireho 39065569331642446be05292e3e1f8a51218827168cdclaireho 39075569331642446be05292e3e1f8a51218827168cdclairehoHB_Error HB_GSUB_Query_Languages( HB_GSUBHeader* gsub, 39085569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort script_index, 39095569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt** language_tag_list ) 39105569331642446be05292e3e1f8a51218827168cdclaireho{ 39115569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n; 39125569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 39135569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt* ltl; 39145569331642446be05292e3e1f8a51218827168cdclaireho 39155569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptList* sl; 39165569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptRecord* sr; 39175569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptTable* s; 39185569331642446be05292e3e1f8a51218827168cdclaireho HB_LangSysRecord* lsr; 39195569331642446be05292e3e1f8a51218827168cdclaireho 39205569331642446be05292e3e1f8a51218827168cdclaireho 39215569331642446be05292e3e1f8a51218827168cdclaireho if ( !gsub || !language_tag_list ) 39225569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 39235569331642446be05292e3e1f8a51218827168cdclaireho 39245569331642446be05292e3e1f8a51218827168cdclaireho sl = &gsub->ScriptList; 39255569331642446be05292e3e1f8a51218827168cdclaireho sr = sl->ScriptRecord; 39265569331642446be05292e3e1f8a51218827168cdclaireho 39275569331642446be05292e3e1f8a51218827168cdclaireho if ( script_index >= sl->ScriptCount ) 39285569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 39295569331642446be05292e3e1f8a51218827168cdclaireho 39305569331642446be05292e3e1f8a51218827168cdclaireho s = &sr[script_index].Script; 39315569331642446be05292e3e1f8a51218827168cdclaireho lsr = s->LangSysRecord; 39325569331642446be05292e3e1f8a51218827168cdclaireho 39335569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( ltl, s->LangSysCount + 1, HB_UInt ) ) 39345569331642446be05292e3e1f8a51218827168cdclaireho return error; 39355569331642446be05292e3e1f8a51218827168cdclaireho 39365569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < s->LangSysCount; n++ ) 39375569331642446be05292e3e1f8a51218827168cdclaireho ltl[n] = lsr[n].LangSysTag; 39385569331642446be05292e3e1f8a51218827168cdclaireho ltl[n] = 0; 39395569331642446be05292e3e1f8a51218827168cdclaireho 39405569331642446be05292e3e1f8a51218827168cdclaireho *language_tag_list = ltl; 39415569331642446be05292e3e1f8a51218827168cdclaireho 39425569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 39435569331642446be05292e3e1f8a51218827168cdclaireho} 39445569331642446be05292e3e1f8a51218827168cdclaireho 39455569331642446be05292e3e1f8a51218827168cdclaireho 39465569331642446be05292e3e1f8a51218827168cdclaireho/* selecting 0xFFFF for language_index asks for the values of the 39475569331642446be05292e3e1f8a51218827168cdclaireho default language (DefaultLangSys) */ 39485569331642446be05292e3e1f8a51218827168cdclaireho 39495569331642446be05292e3e1f8a51218827168cdclaireho 39505569331642446be05292e3e1f8a51218827168cdclairehoHB_Error HB_GSUB_Query_Features( HB_GSUBHeader* gsub, 39515569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort script_index, 39525569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort language_index, 39535569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt** feature_tag_list ) 39545569331642446be05292e3e1f8a51218827168cdclaireho{ 39555569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n; 39565569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 39575569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt* ftl; 39585569331642446be05292e3e1f8a51218827168cdclaireho 39595569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptList* sl; 39605569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptRecord* sr; 39615569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptTable* s; 39625569331642446be05292e3e1f8a51218827168cdclaireho HB_LangSysRecord* lsr; 39635569331642446be05292e3e1f8a51218827168cdclaireho HB_LangSys* ls; 39645569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* fi; 39655569331642446be05292e3e1f8a51218827168cdclaireho 39665569331642446be05292e3e1f8a51218827168cdclaireho HB_FeatureList* fl; 39675569331642446be05292e3e1f8a51218827168cdclaireho HB_FeatureRecord* fr; 39685569331642446be05292e3e1f8a51218827168cdclaireho 39695569331642446be05292e3e1f8a51218827168cdclaireho 39705569331642446be05292e3e1f8a51218827168cdclaireho if ( !gsub || !feature_tag_list ) 39715569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 39725569331642446be05292e3e1f8a51218827168cdclaireho 39735569331642446be05292e3e1f8a51218827168cdclaireho sl = &gsub->ScriptList; 39745569331642446be05292e3e1f8a51218827168cdclaireho sr = sl->ScriptRecord; 39755569331642446be05292e3e1f8a51218827168cdclaireho 39765569331642446be05292e3e1f8a51218827168cdclaireho fl = &gsub->FeatureList; 39775569331642446be05292e3e1f8a51218827168cdclaireho fr = fl->FeatureRecord; 39785569331642446be05292e3e1f8a51218827168cdclaireho 39795569331642446be05292e3e1f8a51218827168cdclaireho if ( script_index >= sl->ScriptCount ) 39805569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 39815569331642446be05292e3e1f8a51218827168cdclaireho 39825569331642446be05292e3e1f8a51218827168cdclaireho s = &sr[script_index].Script; 39835569331642446be05292e3e1f8a51218827168cdclaireho lsr = s->LangSysRecord; 39845569331642446be05292e3e1f8a51218827168cdclaireho 39855569331642446be05292e3e1f8a51218827168cdclaireho if ( language_index == 0xFFFF ) 39865569331642446be05292e3e1f8a51218827168cdclaireho ls = &s->DefaultLangSys; 39875569331642446be05292e3e1f8a51218827168cdclaireho else 39885569331642446be05292e3e1f8a51218827168cdclaireho { 39895569331642446be05292e3e1f8a51218827168cdclaireho if ( language_index >= s->LangSysCount ) 39905569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 39915569331642446be05292e3e1f8a51218827168cdclaireho 39925569331642446be05292e3e1f8a51218827168cdclaireho ls = &lsr[language_index].LangSys; 39935569331642446be05292e3e1f8a51218827168cdclaireho } 39945569331642446be05292e3e1f8a51218827168cdclaireho 39955569331642446be05292e3e1f8a51218827168cdclaireho fi = ls->FeatureIndex; 39965569331642446be05292e3e1f8a51218827168cdclaireho 39975569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( ftl, ls->FeatureCount + 1, HB_UInt ) ) 39985569331642446be05292e3e1f8a51218827168cdclaireho return error; 39995569331642446be05292e3e1f8a51218827168cdclaireho 40005569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < ls->FeatureCount; n++ ) 40015569331642446be05292e3e1f8a51218827168cdclaireho { 40025569331642446be05292e3e1f8a51218827168cdclaireho if ( fi[n] >= fl->FeatureCount ) 40035569331642446be05292e3e1f8a51218827168cdclaireho { 40045569331642446be05292e3e1f8a51218827168cdclaireho FREE( ftl ); 40055569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable_Format); 40065569331642446be05292e3e1f8a51218827168cdclaireho } 40075569331642446be05292e3e1f8a51218827168cdclaireho ftl[n] = fr[fi[n]].FeatureTag; 40085569331642446be05292e3e1f8a51218827168cdclaireho } 40095569331642446be05292e3e1f8a51218827168cdclaireho ftl[n] = 0; 40105569331642446be05292e3e1f8a51218827168cdclaireho 40115569331642446be05292e3e1f8a51218827168cdclaireho *feature_tag_list = ftl; 40125569331642446be05292e3e1f8a51218827168cdclaireho 40135569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 40145569331642446be05292e3e1f8a51218827168cdclaireho} 40155569331642446be05292e3e1f8a51218827168cdclaireho 40165569331642446be05292e3e1f8a51218827168cdclaireho 40175569331642446be05292e3e1f8a51218827168cdclaireho/* Do an individual subtable lookup. Returns HB_Err_Ok if substitution 40185569331642446be05292e3e1f8a51218827168cdclaireho has been done, or HB_Err_Not_Covered if not. */ 40195569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error GSUB_Do_Glyph_Lookup( HB_GSUBHeader* gsub, 40205569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort lookup_index, 40215569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 40225569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 40235569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 40245569331642446be05292e3e1f8a51218827168cdclaireho{ 40255569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error = HB_Err_Not_Covered; 40265569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort i, flags, lookup_count; 40275569331642446be05292e3e1f8a51218827168cdclaireho HB_Lookup* lo; 40285569331642446be05292e3e1f8a51218827168cdclaireho int lookup_type; 40295569331642446be05292e3e1f8a51218827168cdclaireho 40305569331642446be05292e3e1f8a51218827168cdclaireho nesting_level++; 40315569331642446be05292e3e1f8a51218827168cdclaireho 40325569331642446be05292e3e1f8a51218827168cdclaireho if ( nesting_level > HB_MAX_NESTING_LEVEL ) 40335569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Not_Covered); /* ERR() call intended */ 40345569331642446be05292e3e1f8a51218827168cdclaireho 40355569331642446be05292e3e1f8a51218827168cdclaireho lookup_count = gsub->LookupList.LookupCount; 40365569331642446be05292e3e1f8a51218827168cdclaireho if (lookup_index >= lookup_count) 40375569331642446be05292e3e1f8a51218827168cdclaireho return error; 40385569331642446be05292e3e1f8a51218827168cdclaireho 40395569331642446be05292e3e1f8a51218827168cdclaireho lo = &gsub->LookupList.Lookup[lookup_index]; 40405569331642446be05292e3e1f8a51218827168cdclaireho flags = lo->LookupFlag; 40415569331642446be05292e3e1f8a51218827168cdclaireho lookup_type = lo->LookupType; 40425569331642446be05292e3e1f8a51218827168cdclaireho 40435569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 0; i < lo->SubTableCount; i++ ) 40445569331642446be05292e3e1f8a51218827168cdclaireho { 40455569331642446be05292e3e1f8a51218827168cdclaireho HB_GSUB_SubTable *st = &lo->SubTable[i].st.gsub; 40465569331642446be05292e3e1f8a51218827168cdclaireho 40475569331642446be05292e3e1f8a51218827168cdclaireho switch (lookup_type) { 40485569331642446be05292e3e1f8a51218827168cdclaireho case HB_GSUB_LOOKUP_SINGLE: 40495569331642446be05292e3e1f8a51218827168cdclaireho error = Lookup_SingleSubst ( gsub, st, buffer, flags, context_length, nesting_level ); break; 40505569331642446be05292e3e1f8a51218827168cdclaireho case HB_GSUB_LOOKUP_MULTIPLE: 40515569331642446be05292e3e1f8a51218827168cdclaireho error = Lookup_MultipleSubst ( gsub, st, buffer, flags, context_length, nesting_level ); break; 40525569331642446be05292e3e1f8a51218827168cdclaireho case HB_GSUB_LOOKUP_ALTERNATE: 40535569331642446be05292e3e1f8a51218827168cdclaireho error = Lookup_AlternateSubst ( gsub, st, buffer, flags, context_length, nesting_level ); break; 40545569331642446be05292e3e1f8a51218827168cdclaireho case HB_GSUB_LOOKUP_LIGATURE: 40555569331642446be05292e3e1f8a51218827168cdclaireho error = Lookup_LigatureSubst ( gsub, st, buffer, flags, context_length, nesting_level ); break; 40565569331642446be05292e3e1f8a51218827168cdclaireho case HB_GSUB_LOOKUP_CONTEXT: 40575569331642446be05292e3e1f8a51218827168cdclaireho error = Lookup_ContextSubst ( gsub, st, buffer, flags, context_length, nesting_level ); break; 40585569331642446be05292e3e1f8a51218827168cdclaireho case HB_GSUB_LOOKUP_CHAIN: 40595569331642446be05292e3e1f8a51218827168cdclaireho error = Lookup_ChainContextSubst ( gsub, st, buffer, flags, context_length, nesting_level ); break; 40605569331642446be05292e3e1f8a51218827168cdclaireho /*case HB_GSUB_LOOKUP_EXTENSION: 40615569331642446be05292e3e1f8a51218827168cdclaireho error = Lookup_ExtensionSubst ( gsub, st, buffer, flags, context_length, nesting_level ); break;*/ 40625569331642446be05292e3e1f8a51218827168cdclaireho case HB_GSUB_LOOKUP_REVERSE_CHAIN: 40635569331642446be05292e3e1f8a51218827168cdclaireho error = Lookup_ReverseChainContextSubst ( gsub, st, buffer, flags, context_length, nesting_level ); break; 40645569331642446be05292e3e1f8a51218827168cdclaireho default: 40655569331642446be05292e3e1f8a51218827168cdclaireho error = HB_Err_Not_Covered; 40665569331642446be05292e3e1f8a51218827168cdclaireho }; 40675569331642446be05292e3e1f8a51218827168cdclaireho 40685569331642446be05292e3e1f8a51218827168cdclaireho /* Check whether we have a successful substitution or an error other 40695569331642446be05292e3e1f8a51218827168cdclaireho than HB_Err_Not_Covered */ 40705569331642446be05292e3e1f8a51218827168cdclaireho if ( error != HB_Err_Not_Covered ) 40715569331642446be05292e3e1f8a51218827168cdclaireho return error; 40725569331642446be05292e3e1f8a51218827168cdclaireho } 40735569331642446be05292e3e1f8a51218827168cdclaireho 40745569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 40755569331642446be05292e3e1f8a51218827168cdclaireho} 40765569331642446be05292e3e1f8a51218827168cdclaireho 40775569331642446be05292e3e1f8a51218827168cdclaireho 40785569331642446be05292e3e1f8a51218827168cdclairehoHB_INTERNAL HB_Error 40795569331642446be05292e3e1f8a51218827168cdclaireho_HB_GSUB_Load_SubTable( HB_GSUB_SubTable* st, 40805569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream, 40815569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort lookup_type ) 40825569331642446be05292e3e1f8a51218827168cdclaireho{ 40835569331642446be05292e3e1f8a51218827168cdclaireho switch (lookup_type) { 40845569331642446be05292e3e1f8a51218827168cdclaireho case HB_GSUB_LOOKUP_SINGLE: return Load_SingleSubst ( st, stream ); 40855569331642446be05292e3e1f8a51218827168cdclaireho case HB_GSUB_LOOKUP_MULTIPLE: return Load_MultipleSubst ( st, stream ); 40865569331642446be05292e3e1f8a51218827168cdclaireho case HB_GSUB_LOOKUP_ALTERNATE: return Load_AlternateSubst ( st, stream ); 40875569331642446be05292e3e1f8a51218827168cdclaireho case HB_GSUB_LOOKUP_LIGATURE: return Load_LigatureSubst ( st, stream ); 40885569331642446be05292e3e1f8a51218827168cdclaireho case HB_GSUB_LOOKUP_CONTEXT: return Load_ContextSubst ( st, stream ); 40895569331642446be05292e3e1f8a51218827168cdclaireho case HB_GSUB_LOOKUP_CHAIN: return Load_ChainContextSubst ( st, stream ); 40905569331642446be05292e3e1f8a51218827168cdclaireho /*case HB_GSUB_LOOKUP_EXTENSION: return Load_ExtensionSubst ( st, stream );*/ 40915569331642446be05292e3e1f8a51218827168cdclaireho case HB_GSUB_LOOKUP_REVERSE_CHAIN: return Load_ReverseChainContextSubst ( st, stream ); 40925569331642446be05292e3e1f8a51218827168cdclaireho default: return ERR(HB_Err_Invalid_SubTable_Format); 40935569331642446be05292e3e1f8a51218827168cdclaireho }; 40945569331642446be05292e3e1f8a51218827168cdclaireho} 40955569331642446be05292e3e1f8a51218827168cdclaireho 40965569331642446be05292e3e1f8a51218827168cdclaireho 40975569331642446be05292e3e1f8a51218827168cdclairehoHB_INTERNAL void 40985569331642446be05292e3e1f8a51218827168cdclaireho_HB_GSUB_Free_SubTable( HB_GSUB_SubTable* st, 40995569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort lookup_type ) 41005569331642446be05292e3e1f8a51218827168cdclaireho{ 41015569331642446be05292e3e1f8a51218827168cdclaireho switch ( lookup_type ) { 41025569331642446be05292e3e1f8a51218827168cdclaireho case HB_GSUB_LOOKUP_SINGLE: Free_SingleSubst ( st ); return; 41035569331642446be05292e3e1f8a51218827168cdclaireho case HB_GSUB_LOOKUP_MULTIPLE: Free_MultipleSubst ( st ); return; 41045569331642446be05292e3e1f8a51218827168cdclaireho case HB_GSUB_LOOKUP_ALTERNATE: Free_AlternateSubst ( st ); return; 41055569331642446be05292e3e1f8a51218827168cdclaireho case HB_GSUB_LOOKUP_LIGATURE: Free_LigatureSubst ( st ); return; 41065569331642446be05292e3e1f8a51218827168cdclaireho case HB_GSUB_LOOKUP_CONTEXT: Free_ContextSubst ( st ); return; 41075569331642446be05292e3e1f8a51218827168cdclaireho case HB_GSUB_LOOKUP_CHAIN: Free_ChainContextSubst ( st ); return; 41085569331642446be05292e3e1f8a51218827168cdclaireho /*case HB_GSUB_LOOKUP_EXTENSION: Free_ExtensionSubst ( st ); return;*/ 41095569331642446be05292e3e1f8a51218827168cdclaireho case HB_GSUB_LOOKUP_REVERSE_CHAIN: Free_ReverseChainContextSubst ( st ); return; 41105569331642446be05292e3e1f8a51218827168cdclaireho default: return; 41115569331642446be05292e3e1f8a51218827168cdclaireho }; 41125569331642446be05292e3e1f8a51218827168cdclaireho} 41135569331642446be05292e3e1f8a51218827168cdclaireho 41145569331642446be05292e3e1f8a51218827168cdclaireho 41155569331642446be05292e3e1f8a51218827168cdclaireho 41165569331642446be05292e3e1f8a51218827168cdclaireho/* apply one lookup to the input string object */ 41175569331642446be05292e3e1f8a51218827168cdclaireho 41185569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error GSUB_Do_String_Lookup( HB_GSUBHeader* gsub, 41195569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort lookup_index, 41205569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer ) 41215569331642446be05292e3e1f8a51218827168cdclaireho{ 41225569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error, retError = HB_Err_Not_Covered; 41235569331642446be05292e3e1f8a51218827168cdclaireho 41245569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt* properties = gsub->LookupList.Properties; 41255569331642446be05292e3e1f8a51218827168cdclaireho int lookup_type = gsub->LookupList.Lookup[lookup_index].LookupType; 41265569331642446be05292e3e1f8a51218827168cdclaireho 41275569331642446be05292e3e1f8a51218827168cdclaireho const int nesting_level = 0; 41285569331642446be05292e3e1f8a51218827168cdclaireho /* 0xFFFF indicates that we don't have a context length yet */ 41295569331642446be05292e3e1f8a51218827168cdclaireho const HB_UShort context_length = 0xFFFF; 41305569331642446be05292e3e1f8a51218827168cdclaireho 41315569331642446be05292e3e1f8a51218827168cdclaireho switch (lookup_type) { 41325569331642446be05292e3e1f8a51218827168cdclaireho 41335569331642446be05292e3e1f8a51218827168cdclaireho case HB_GSUB_LOOKUP_SINGLE: 41345569331642446be05292e3e1f8a51218827168cdclaireho case HB_GSUB_LOOKUP_MULTIPLE: 41355569331642446be05292e3e1f8a51218827168cdclaireho case HB_GSUB_LOOKUP_ALTERNATE: 41365569331642446be05292e3e1f8a51218827168cdclaireho case HB_GSUB_LOOKUP_LIGATURE: 41375569331642446be05292e3e1f8a51218827168cdclaireho case HB_GSUB_LOOKUP_CONTEXT: 41385569331642446be05292e3e1f8a51218827168cdclaireho case HB_GSUB_LOOKUP_CHAIN: 41395569331642446be05292e3e1f8a51218827168cdclaireho /* in/out forward substitution (implemented lazy) */ 41405569331642446be05292e3e1f8a51218827168cdclaireho 41415569331642446be05292e3e1f8a51218827168cdclaireho _hb_buffer_clear_output ( buffer ); 41425569331642446be05292e3e1f8a51218827168cdclaireho buffer->in_pos = 0; 41435569331642446be05292e3e1f8a51218827168cdclaireho while ( buffer->in_pos < buffer->in_length ) 41445569331642446be05292e3e1f8a51218827168cdclaireho { 41455569331642446be05292e3e1f8a51218827168cdclaireho if ( ~IN_PROPERTIES( buffer->in_pos ) & properties[lookup_index] ) 41465569331642446be05292e3e1f8a51218827168cdclaireho { 41475569331642446be05292e3e1f8a51218827168cdclaireho error = GSUB_Do_Glyph_Lookup( gsub, lookup_index, buffer, context_length, nesting_level ); 41485569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 41495569331642446be05292e3e1f8a51218827168cdclaireho { 41505569331642446be05292e3e1f8a51218827168cdclaireho if ( error != HB_Err_Not_Covered ) 41515569331642446be05292e3e1f8a51218827168cdclaireho return error; 41525569331642446be05292e3e1f8a51218827168cdclaireho } 41535569331642446be05292e3e1f8a51218827168cdclaireho else 41545569331642446be05292e3e1f8a51218827168cdclaireho retError = error; 41555569331642446be05292e3e1f8a51218827168cdclaireho } 41565569331642446be05292e3e1f8a51218827168cdclaireho else 41575569331642446be05292e3e1f8a51218827168cdclaireho error = HB_Err_Not_Covered; 41585569331642446be05292e3e1f8a51218827168cdclaireho 41595569331642446be05292e3e1f8a51218827168cdclaireho if ( error == HB_Err_Not_Covered ) 41605569331642446be05292e3e1f8a51218827168cdclaireho if ( COPY_Glyph ( buffer ) ) 41615569331642446be05292e3e1f8a51218827168cdclaireho return error; 41625569331642446be05292e3e1f8a51218827168cdclaireho } 41635569331642446be05292e3e1f8a51218827168cdclaireho /* we shouldn't swap if error occurred. 41645569331642446be05292e3e1f8a51218827168cdclaireho * 41655569331642446be05292e3e1f8a51218827168cdclaireho * also don't swap if nothing changed (ie HB_Err_Not_Covered). 41665569331642446be05292e3e1f8a51218827168cdclaireho * shouldn't matter in that case though. 41675569331642446be05292e3e1f8a51218827168cdclaireho */ 41685569331642446be05292e3e1f8a51218827168cdclaireho if ( retError == HB_Err_Ok ) 41695569331642446be05292e3e1f8a51218827168cdclaireho _hb_buffer_swap( buffer ); 41705569331642446be05292e3e1f8a51218827168cdclaireho 41715569331642446be05292e3e1f8a51218827168cdclaireho return retError; 41725569331642446be05292e3e1f8a51218827168cdclaireho 41735569331642446be05292e3e1f8a51218827168cdclaireho case HB_GSUB_LOOKUP_REVERSE_CHAIN: 41745569331642446be05292e3e1f8a51218827168cdclaireho /* in-place backward substitution */ 41755569331642446be05292e3e1f8a51218827168cdclaireho 41765569331642446be05292e3e1f8a51218827168cdclaireho buffer->in_pos = buffer->in_length - 1; 41775569331642446be05292e3e1f8a51218827168cdclaireho do 41785569331642446be05292e3e1f8a51218827168cdclaireho { 41795569331642446be05292e3e1f8a51218827168cdclaireho if ( ~IN_PROPERTIES( buffer->in_pos ) & properties[lookup_index] ) 41805569331642446be05292e3e1f8a51218827168cdclaireho { 41815569331642446be05292e3e1f8a51218827168cdclaireho error = GSUB_Do_Glyph_Lookup( gsub, lookup_index, buffer, context_length, nesting_level ); 41825569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 41835569331642446be05292e3e1f8a51218827168cdclaireho { 41845569331642446be05292e3e1f8a51218827168cdclaireho if ( error != HB_Err_Not_Covered ) 41855569331642446be05292e3e1f8a51218827168cdclaireho return error; 41865569331642446be05292e3e1f8a51218827168cdclaireho } 41875569331642446be05292e3e1f8a51218827168cdclaireho else 41885569331642446be05292e3e1f8a51218827168cdclaireho retError = error; 41895569331642446be05292e3e1f8a51218827168cdclaireho } 41905569331642446be05292e3e1f8a51218827168cdclaireho else 41915569331642446be05292e3e1f8a51218827168cdclaireho error = HB_Err_Not_Covered; 41925569331642446be05292e3e1f8a51218827168cdclaireho 41935569331642446be05292e3e1f8a51218827168cdclaireho if ( error == HB_Err_Not_Covered ) 41945569331642446be05292e3e1f8a51218827168cdclaireho buffer->in_pos--; 41955569331642446be05292e3e1f8a51218827168cdclaireho } 41965569331642446be05292e3e1f8a51218827168cdclaireho while ((HB_Int) buffer->in_pos >= 0); 41975569331642446be05292e3e1f8a51218827168cdclaireho 41985569331642446be05292e3e1f8a51218827168cdclaireho return retError; 41995569331642446be05292e3e1f8a51218827168cdclaireho 42005569331642446be05292e3e1f8a51218827168cdclaireho /*case HB_GSUB_LOOKUP_EXTENSION:*/ 42015569331642446be05292e3e1f8a51218827168cdclaireho default: 42025569331642446be05292e3e1f8a51218827168cdclaireho return retError; 42035569331642446be05292e3e1f8a51218827168cdclaireho }; 42045569331642446be05292e3e1f8a51218827168cdclaireho} 42055569331642446be05292e3e1f8a51218827168cdclaireho 42065569331642446be05292e3e1f8a51218827168cdclaireho 42075569331642446be05292e3e1f8a51218827168cdclairehoHB_Error HB_GSUB_Add_Feature( HB_GSUBHeader* gsub, 42085569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort feature_index, 42095569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt property ) 42105569331642446be05292e3e1f8a51218827168cdclaireho{ 42115569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort i; 42125569331642446be05292e3e1f8a51218827168cdclaireho 42135569331642446be05292e3e1f8a51218827168cdclaireho HB_Feature feature; 42145569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt* properties; 42155569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* index; 42165569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort lookup_count; 42175569331642446be05292e3e1f8a51218827168cdclaireho 42185569331642446be05292e3e1f8a51218827168cdclaireho /* Each feature can only be added once */ 42195569331642446be05292e3e1f8a51218827168cdclaireho 42205569331642446be05292e3e1f8a51218827168cdclaireho if ( !gsub || 42215569331642446be05292e3e1f8a51218827168cdclaireho feature_index >= gsub->FeatureList.FeatureCount || 42225569331642446be05292e3e1f8a51218827168cdclaireho gsub->FeatureList.ApplyCount == gsub->FeatureList.FeatureCount ) 42235569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 42245569331642446be05292e3e1f8a51218827168cdclaireho 42255569331642446be05292e3e1f8a51218827168cdclaireho gsub->FeatureList.ApplyOrder[gsub->FeatureList.ApplyCount++] = feature_index; 42265569331642446be05292e3e1f8a51218827168cdclaireho 42275569331642446be05292e3e1f8a51218827168cdclaireho properties = gsub->LookupList.Properties; 42285569331642446be05292e3e1f8a51218827168cdclaireho 42295569331642446be05292e3e1f8a51218827168cdclaireho feature = gsub->FeatureList.FeatureRecord[feature_index].Feature; 42305569331642446be05292e3e1f8a51218827168cdclaireho index = feature.LookupListIndex; 42315569331642446be05292e3e1f8a51218827168cdclaireho lookup_count = gsub->LookupList.LookupCount; 42325569331642446be05292e3e1f8a51218827168cdclaireho 42335569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 0; i < feature.LookupListCount; i++ ) 42345569331642446be05292e3e1f8a51218827168cdclaireho { 42355569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort lookup_index = index[i]; 42365569331642446be05292e3e1f8a51218827168cdclaireho if (lookup_index < lookup_count) 42375569331642446be05292e3e1f8a51218827168cdclaireho properties[lookup_index] |= property; 42385569331642446be05292e3e1f8a51218827168cdclaireho } 42395569331642446be05292e3e1f8a51218827168cdclaireho 42405569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 42415569331642446be05292e3e1f8a51218827168cdclaireho} 42425569331642446be05292e3e1f8a51218827168cdclaireho 42435569331642446be05292e3e1f8a51218827168cdclaireho 42445569331642446be05292e3e1f8a51218827168cdclaireho 42455569331642446be05292e3e1f8a51218827168cdclairehoHB_Error HB_GSUB_Clear_Features( HB_GSUBHeader* gsub ) 42465569331642446be05292e3e1f8a51218827168cdclaireho{ 42475569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort i; 42485569331642446be05292e3e1f8a51218827168cdclaireho 42495569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt* properties; 42505569331642446be05292e3e1f8a51218827168cdclaireho 42515569331642446be05292e3e1f8a51218827168cdclaireho 42525569331642446be05292e3e1f8a51218827168cdclaireho if ( !gsub ) 42535569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 42545569331642446be05292e3e1f8a51218827168cdclaireho 42555569331642446be05292e3e1f8a51218827168cdclaireho gsub->FeatureList.ApplyCount = 0; 42565569331642446be05292e3e1f8a51218827168cdclaireho 42575569331642446be05292e3e1f8a51218827168cdclaireho properties = gsub->LookupList.Properties; 42585569331642446be05292e3e1f8a51218827168cdclaireho 42595569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 0; i < gsub->LookupList.LookupCount; i++ ) 42605569331642446be05292e3e1f8a51218827168cdclaireho properties[i] = 0; 42615569331642446be05292e3e1f8a51218827168cdclaireho 42625569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 42635569331642446be05292e3e1f8a51218827168cdclaireho} 42645569331642446be05292e3e1f8a51218827168cdclaireho 42655569331642446be05292e3e1f8a51218827168cdclaireho 42665569331642446be05292e3e1f8a51218827168cdclaireho 42675569331642446be05292e3e1f8a51218827168cdclairehoHB_Error HB_GSUB_Register_Alternate_Function( HB_GSUBHeader* gsub, 42685569331642446be05292e3e1f8a51218827168cdclaireho HB_AltFunction altfunc, 42695569331642446be05292e3e1f8a51218827168cdclaireho void* data ) 42705569331642446be05292e3e1f8a51218827168cdclaireho{ 42715569331642446be05292e3e1f8a51218827168cdclaireho if ( !gsub ) 42725569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 42735569331642446be05292e3e1f8a51218827168cdclaireho 42745569331642446be05292e3e1f8a51218827168cdclaireho gsub->altfunc = altfunc; 42755569331642446be05292e3e1f8a51218827168cdclaireho gsub->data = data; 42765569331642446be05292e3e1f8a51218827168cdclaireho 42775569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 42785569331642446be05292e3e1f8a51218827168cdclaireho} 42795569331642446be05292e3e1f8a51218827168cdclaireho 42805569331642446be05292e3e1f8a51218827168cdclaireho/* returns error if one happened, otherwise returns HB_Err_Not_Covered if no 42815569331642446be05292e3e1f8a51218827168cdclaireho * feature were applied, or HB_Err_Ok otherwise. 42825569331642446be05292e3e1f8a51218827168cdclaireho */ 42835569331642446be05292e3e1f8a51218827168cdclairehoHB_Error HB_GSUB_Apply_String( HB_GSUBHeader* gsub, 42845569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer ) 42855569331642446be05292e3e1f8a51218827168cdclaireho{ 42865569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error, retError = HB_Err_Not_Covered; 42875569331642446be05292e3e1f8a51218827168cdclaireho int i, j, lookup_count, num_features; 42885569331642446be05292e3e1f8a51218827168cdclaireho 42895569331642446be05292e3e1f8a51218827168cdclaireho if ( !gsub || 42905569331642446be05292e3e1f8a51218827168cdclaireho !buffer) 42915569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 42925569331642446be05292e3e1f8a51218827168cdclaireho 42935569331642446be05292e3e1f8a51218827168cdclaireho if ( buffer->in_length == 0 ) 42945569331642446be05292e3e1f8a51218827168cdclaireho return retError; 42955569331642446be05292e3e1f8a51218827168cdclaireho 42965569331642446be05292e3e1f8a51218827168cdclaireho lookup_count = gsub->LookupList.LookupCount; 42975569331642446be05292e3e1f8a51218827168cdclaireho num_features = gsub->FeatureList.ApplyCount; 42985569331642446be05292e3e1f8a51218827168cdclaireho 42995569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 0; i < num_features; i++) 43005569331642446be05292e3e1f8a51218827168cdclaireho { 43015569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort feature_index = gsub->FeatureList.ApplyOrder[i]; 43025569331642446be05292e3e1f8a51218827168cdclaireho HB_Feature feature = gsub->FeatureList.FeatureRecord[feature_index].Feature; 43035569331642446be05292e3e1f8a51218827168cdclaireho 43045569331642446be05292e3e1f8a51218827168cdclaireho for ( j = 0; j < feature.LookupListCount; j++ ) 43055569331642446be05292e3e1f8a51218827168cdclaireho { 43065569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort lookup_index = feature.LookupListIndex[j]; 43075569331642446be05292e3e1f8a51218827168cdclaireho 43085569331642446be05292e3e1f8a51218827168cdclaireho /* Skip nonexistant lookups */ 43095569331642446be05292e3e1f8a51218827168cdclaireho if (lookup_index >= lookup_count) 43105569331642446be05292e3e1f8a51218827168cdclaireho continue; 43115569331642446be05292e3e1f8a51218827168cdclaireho 43125569331642446be05292e3e1f8a51218827168cdclaireho error = GSUB_Do_String_Lookup( gsub, lookup_index, buffer ); 43135569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 43145569331642446be05292e3e1f8a51218827168cdclaireho { 43155569331642446be05292e3e1f8a51218827168cdclaireho if ( error != HB_Err_Not_Covered ) 43165569331642446be05292e3e1f8a51218827168cdclaireho return error; 43175569331642446be05292e3e1f8a51218827168cdclaireho } 43185569331642446be05292e3e1f8a51218827168cdclaireho else 43195569331642446be05292e3e1f8a51218827168cdclaireho retError = error; 43205569331642446be05292e3e1f8a51218827168cdclaireho } 43215569331642446be05292e3e1f8a51218827168cdclaireho } 43225569331642446be05292e3e1f8a51218827168cdclaireho 43235569331642446be05292e3e1f8a51218827168cdclaireho error = retError; 43245569331642446be05292e3e1f8a51218827168cdclaireho 43255569331642446be05292e3e1f8a51218827168cdclaireho return error; 43265569331642446be05292e3e1f8a51218827168cdclaireho} 43275569331642446be05292e3e1f8a51218827168cdclaireho 43285569331642446be05292e3e1f8a51218827168cdclaireho 43295569331642446be05292e3e1f8a51218827168cdclaireho/* END */ 4330