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-gpos-private.h" 315569331642446be05292e3e1f8a51218827168cdclaireho#include "harfbuzz-open-private.h" 325569331642446be05292e3e1f8a51218827168cdclaireho#include "harfbuzz-gdef-private.h" 335569331642446be05292e3e1f8a51218827168cdclaireho#include "harfbuzz-shaper.h" 345569331642446be05292e3e1f8a51218827168cdclaireho 355569331642446be05292e3e1f8a51218827168cdclairehostruct GPOS_Instance_ 365569331642446be05292e3e1f8a51218827168cdclaireho{ 375569331642446be05292e3e1f8a51218827168cdclaireho HB_GPOSHeader* gpos; 385569331642446be05292e3e1f8a51218827168cdclaireho HB_Font font; 395569331642446be05292e3e1f8a51218827168cdclaireho HB_Bool dvi; 405569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort load_flags; /* how the glyph should be loaded */ 415569331642446be05292e3e1f8a51218827168cdclaireho HB_Bool r2l; 425569331642446be05292e3e1f8a51218827168cdclaireho 435569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort last; /* the last valid glyph -- used 445569331642446be05292e3e1f8a51218827168cdclaireho with cursive positioning */ 455569331642446be05292e3e1f8a51218827168cdclaireho HB_Fixed anchor_x; /* the coordinates of the anchor point */ 465569331642446be05292e3e1f8a51218827168cdclaireho HB_Fixed anchor_y; /* of the last valid glyph */ 475569331642446be05292e3e1f8a51218827168cdclaireho}; 485569331642446be05292e3e1f8a51218827168cdclaireho 495569331642446be05292e3e1f8a51218827168cdclairehotypedef struct GPOS_Instance_ GPOS_Instance; 505569331642446be05292e3e1f8a51218827168cdclaireho 515569331642446be05292e3e1f8a51218827168cdclaireho 525569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error GPOS_Do_Glyph_Lookup( GPOS_Instance* gpi, 535569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort lookup_index, 545569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 555569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 565569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ); 575569331642446be05292e3e1f8a51218827168cdclaireho 585569331642446be05292e3e1f8a51218827168cdclaireho 595569331642446be05292e3e1f8a51218827168cdclaireho 6057e6107a9d66a9a97b146def0ef38c010f954be6claireho#ifdef HB_SUPPORT_MULTIPLE_MASTER 615569331642446be05292e3e1f8a51218827168cdclaireho/* the client application must replace this with something more 625569331642446be05292e3e1f8a51218827168cdclaireho meaningful if multiple master fonts are to be supported. */ 635569331642446be05292e3e1f8a51218827168cdclaireho 645569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error default_mmfunc( HB_Font font, 655569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort metric_id, 665569331642446be05292e3e1f8a51218827168cdclaireho HB_Fixed* metric_value, 675569331642446be05292e3e1f8a51218827168cdclaireho void* data ) 685569331642446be05292e3e1f8a51218827168cdclaireho{ 695569331642446be05292e3e1f8a51218827168cdclaireho HB_UNUSED(font); 705569331642446be05292e3e1f8a51218827168cdclaireho HB_UNUSED(metric_id); 715569331642446be05292e3e1f8a51218827168cdclaireho HB_UNUSED(metric_value); 725569331642446be05292e3e1f8a51218827168cdclaireho HB_UNUSED(data); 735569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Not_Covered); /* ERR() call intended */ 745569331642446be05292e3e1f8a51218827168cdclaireho} 7557e6107a9d66a9a97b146def0ef38c010f954be6claireho#endif 765569331642446be05292e3e1f8a51218827168cdclaireho 775569331642446be05292e3e1f8a51218827168cdclaireho 785569331642446be05292e3e1f8a51218827168cdclaireho 795569331642446be05292e3e1f8a51218827168cdclairehoHB_Error HB_Load_GPOS_Table( HB_Stream stream, 805569331642446be05292e3e1f8a51218827168cdclaireho HB_GPOSHeader** retptr, 815569331642446be05292e3e1f8a51218827168cdclaireho HB_GDEFHeader* gdef, 825569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream gdefStream ) 835569331642446be05292e3e1f8a51218827168cdclaireho{ 845569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 855569331642446be05292e3e1f8a51218827168cdclaireho 865569331642446be05292e3e1f8a51218827168cdclaireho HB_GPOSHeader* gpos; 875569331642446be05292e3e1f8a51218827168cdclaireho 885569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 895569331642446be05292e3e1f8a51218827168cdclaireho 905569331642446be05292e3e1f8a51218827168cdclaireho 915569331642446be05292e3e1f8a51218827168cdclaireho if ( !retptr ) 925569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 935569331642446be05292e3e1f8a51218827168cdclaireho 945569331642446be05292e3e1f8a51218827168cdclaireho if ( GOTO_Table( TTAG_GPOS ) ) 955569331642446be05292e3e1f8a51218827168cdclaireho return error; 965569331642446be05292e3e1f8a51218827168cdclaireho 975569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 985569331642446be05292e3e1f8a51218827168cdclaireho 995569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC ( gpos, sizeof( *gpos ) ) ) 1005569331642446be05292e3e1f8a51218827168cdclaireho return error; 1015569331642446be05292e3e1f8a51218827168cdclaireho 10257e6107a9d66a9a97b146def0ef38c010f954be6claireho#ifdef HB_SUPPORT_MULTIPLE_MASTER 1035569331642446be05292e3e1f8a51218827168cdclaireho gpos->mmfunc = default_mmfunc; 10457e6107a9d66a9a97b146def0ef38c010f954be6claireho#endif 1055569331642446be05292e3e1f8a51218827168cdclaireho 1065569331642446be05292e3e1f8a51218827168cdclaireho /* skip version */ 1075569331642446be05292e3e1f8a51218827168cdclaireho 1085569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( base_offset + 4L ) || 1095569331642446be05292e3e1f8a51218827168cdclaireho ACCESS_Frame( 2L ) ) 1105569331642446be05292e3e1f8a51218827168cdclaireho goto Fail4; 1115569331642446be05292e3e1f8a51218827168cdclaireho 1125569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 1135569331642446be05292e3e1f8a51218827168cdclaireho 1145569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 1155569331642446be05292e3e1f8a51218827168cdclaireho 1165569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 1175569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 1185569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_ScriptList( &gpos->ScriptList, 1195569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 1205569331642446be05292e3e1f8a51218827168cdclaireho goto Fail4; 1215569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 1225569331642446be05292e3e1f8a51218827168cdclaireho 1235569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 1245569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 1255569331642446be05292e3e1f8a51218827168cdclaireho 1265569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 1275569331642446be05292e3e1f8a51218827168cdclaireho 1285569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 1295569331642446be05292e3e1f8a51218827168cdclaireho 1305569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 1315569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 1325569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_FeatureList( &gpos->FeatureList, 1335569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 1345569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 1355569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 1365569331642446be05292e3e1f8a51218827168cdclaireho 1375569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 1385569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 1395569331642446be05292e3e1f8a51218827168cdclaireho 1405569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 1415569331642446be05292e3e1f8a51218827168cdclaireho 1425569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 1435569331642446be05292e3e1f8a51218827168cdclaireho 1445569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 1455569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 1465569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_LookupList( &gpos->LookupList, 1475569331642446be05292e3e1f8a51218827168cdclaireho stream, HB_Type_GPOS ) ) != HB_Err_Ok ) 1485569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 1495569331642446be05292e3e1f8a51218827168cdclaireho 1505569331642446be05292e3e1f8a51218827168cdclaireho gpos->gdef = gdef; /* can be NULL */ 1515569331642446be05292e3e1f8a51218827168cdclaireho 1525569331642446be05292e3e1f8a51218827168cdclaireho if ( ( error = _HB_GDEF_LoadMarkAttachClassDef_From_LookupFlags( gdef, gdefStream, 1535569331642446be05292e3e1f8a51218827168cdclaireho gpos->LookupList.Lookup, 1545569331642446be05292e3e1f8a51218827168cdclaireho gpos->LookupList.LookupCount ) ) ) 1555569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 1565569331642446be05292e3e1f8a51218827168cdclaireho 1575569331642446be05292e3e1f8a51218827168cdclaireho *retptr = gpos; 1585569331642446be05292e3e1f8a51218827168cdclaireho 1595569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 1605569331642446be05292e3e1f8a51218827168cdclaireho 1615569331642446be05292e3e1f8a51218827168cdclairehoFail1: 1625569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_LookupList( &gpos->LookupList, HB_Type_GPOS ); 1635569331642446be05292e3e1f8a51218827168cdclaireho 1645569331642446be05292e3e1f8a51218827168cdclairehoFail2: 1655569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_FeatureList( &gpos->FeatureList ); 1665569331642446be05292e3e1f8a51218827168cdclaireho 1675569331642446be05292e3e1f8a51218827168cdclairehoFail3: 1685569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_ScriptList( &gpos->ScriptList ); 1695569331642446be05292e3e1f8a51218827168cdclaireho 1705569331642446be05292e3e1f8a51218827168cdclairehoFail4: 1715569331642446be05292e3e1f8a51218827168cdclaireho FREE( gpos ); 1725569331642446be05292e3e1f8a51218827168cdclaireho 1735569331642446be05292e3e1f8a51218827168cdclaireho return error; 1745569331642446be05292e3e1f8a51218827168cdclaireho} 1755569331642446be05292e3e1f8a51218827168cdclaireho 1765569331642446be05292e3e1f8a51218827168cdclaireho 1775569331642446be05292e3e1f8a51218827168cdclairehoHB_Error HB_Done_GPOS_Table( HB_GPOSHeader* gpos ) 1785569331642446be05292e3e1f8a51218827168cdclaireho{ 1795569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_LookupList( &gpos->LookupList, HB_Type_GPOS ); 1805569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_FeatureList( &gpos->FeatureList ); 1815569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_ScriptList( &gpos->ScriptList ); 1825569331642446be05292e3e1f8a51218827168cdclaireho 1835569331642446be05292e3e1f8a51218827168cdclaireho FREE( gpos ); 1845569331642446be05292e3e1f8a51218827168cdclaireho 1855569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 1865569331642446be05292e3e1f8a51218827168cdclaireho} 1875569331642446be05292e3e1f8a51218827168cdclaireho 1885569331642446be05292e3e1f8a51218827168cdclaireho 1895569331642446be05292e3e1f8a51218827168cdclaireho/***************************** 1905569331642446be05292e3e1f8a51218827168cdclaireho * SubTable related functions 1915569331642446be05292e3e1f8a51218827168cdclaireho *****************************/ 1925569331642446be05292e3e1f8a51218827168cdclaireho 1935569331642446be05292e3e1f8a51218827168cdclaireho/* shared tables */ 1945569331642446be05292e3e1f8a51218827168cdclaireho 1955569331642446be05292e3e1f8a51218827168cdclaireho/* ValueRecord */ 1965569331642446be05292e3e1f8a51218827168cdclaireho 1975569331642446be05292e3e1f8a51218827168cdclaireho/* There is a subtle difference in the specs between a `table' and a 1985569331642446be05292e3e1f8a51218827168cdclaireho `record' -- offsets for device tables in ValueRecords are taken from 1995569331642446be05292e3e1f8a51218827168cdclaireho the parent table and not the parent record. */ 2005569331642446be05292e3e1f8a51218827168cdclaireho 2015569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_ValueRecord( HB_ValueRecord* vr, 2025569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort format, 2035569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt base_offset, 2045569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 2055569331642446be05292e3e1f8a51218827168cdclaireho{ 2065569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 2075569331642446be05292e3e1f8a51218827168cdclaireho 2085569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset; 2095569331642446be05292e3e1f8a51218827168cdclaireho 2105569331642446be05292e3e1f8a51218827168cdclaireho 2115569331642446be05292e3e1f8a51218827168cdclaireho if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT ) 2125569331642446be05292e3e1f8a51218827168cdclaireho { 2135569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 2145569331642446be05292e3e1f8a51218827168cdclaireho return error; 2155569331642446be05292e3e1f8a51218827168cdclaireho 2165569331642446be05292e3e1f8a51218827168cdclaireho vr->XPlacement = GET_Short(); 2175569331642446be05292e3e1f8a51218827168cdclaireho 2185569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 2195569331642446be05292e3e1f8a51218827168cdclaireho } 2205569331642446be05292e3e1f8a51218827168cdclaireho else 2215569331642446be05292e3e1f8a51218827168cdclaireho vr->XPlacement = 0; 2225569331642446be05292e3e1f8a51218827168cdclaireho 2235569331642446be05292e3e1f8a51218827168cdclaireho if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT ) 2245569331642446be05292e3e1f8a51218827168cdclaireho { 2255569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 2265569331642446be05292e3e1f8a51218827168cdclaireho return error; 2275569331642446be05292e3e1f8a51218827168cdclaireho 2285569331642446be05292e3e1f8a51218827168cdclaireho vr->YPlacement = GET_Short(); 2295569331642446be05292e3e1f8a51218827168cdclaireho 2305569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 2315569331642446be05292e3e1f8a51218827168cdclaireho } 2325569331642446be05292e3e1f8a51218827168cdclaireho else 2335569331642446be05292e3e1f8a51218827168cdclaireho vr->YPlacement = 0; 2345569331642446be05292e3e1f8a51218827168cdclaireho 2355569331642446be05292e3e1f8a51218827168cdclaireho if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE ) 2365569331642446be05292e3e1f8a51218827168cdclaireho { 2375569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 2385569331642446be05292e3e1f8a51218827168cdclaireho return error; 2395569331642446be05292e3e1f8a51218827168cdclaireho 2405569331642446be05292e3e1f8a51218827168cdclaireho vr->XAdvance = GET_Short(); 2415569331642446be05292e3e1f8a51218827168cdclaireho 2425569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 2435569331642446be05292e3e1f8a51218827168cdclaireho } 2445569331642446be05292e3e1f8a51218827168cdclaireho else 2455569331642446be05292e3e1f8a51218827168cdclaireho vr->XAdvance = 0; 2465569331642446be05292e3e1f8a51218827168cdclaireho 2475569331642446be05292e3e1f8a51218827168cdclaireho if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE ) 2485569331642446be05292e3e1f8a51218827168cdclaireho { 2495569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 2505569331642446be05292e3e1f8a51218827168cdclaireho return error; 2515569331642446be05292e3e1f8a51218827168cdclaireho 2525569331642446be05292e3e1f8a51218827168cdclaireho vr->YAdvance = GET_Short(); 2535569331642446be05292e3e1f8a51218827168cdclaireho 2545569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 2555569331642446be05292e3e1f8a51218827168cdclaireho } 2565569331642446be05292e3e1f8a51218827168cdclaireho else 2575569331642446be05292e3e1f8a51218827168cdclaireho vr->YAdvance = 0; 2585569331642446be05292e3e1f8a51218827168cdclaireho 25957e6107a9d66a9a97b146def0ef38c010f954be6claireho if ( format & HB_GPOS_FORMAT_HAVE_DEVICE_TABLES ) 26057e6107a9d66a9a97b146def0ef38c010f954be6claireho { 26157e6107a9d66a9a97b146def0ef38c010f954be6claireho if ( ALLOC_ARRAY( vr->DeviceTables, 4, HB_Device ) ) 26257e6107a9d66a9a97b146def0ef38c010f954be6claireho return error; 26357e6107a9d66a9a97b146def0ef38c010f954be6claireho vr->DeviceTables[VR_X_ADVANCE_DEVICE] = 0; 26457e6107a9d66a9a97b146def0ef38c010f954be6claireho vr->DeviceTables[VR_Y_ADVANCE_DEVICE] = 0; 26557e6107a9d66a9a97b146def0ef38c010f954be6claireho vr->DeviceTables[VR_X_PLACEMENT_DEVICE] = 0; 26657e6107a9d66a9a97b146def0ef38c010f954be6claireho vr->DeviceTables[VR_Y_PLACEMENT_DEVICE] = 0; 26757e6107a9d66a9a97b146def0ef38c010f954be6claireho } 26857e6107a9d66a9a97b146def0ef38c010f954be6claireho else 26957e6107a9d66a9a97b146def0ef38c010f954be6claireho { 27057e6107a9d66a9a97b146def0ef38c010f954be6claireho vr->DeviceTables = 0; 27157e6107a9d66a9a97b146def0ef38c010f954be6claireho } 27257e6107a9d66a9a97b146def0ef38c010f954be6claireho 2735569331642446be05292e3e1f8a51218827168cdclaireho if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT_DEVICE ) 2745569331642446be05292e3e1f8a51218827168cdclaireho { 2755569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 27657e6107a9d66a9a97b146def0ef38c010f954be6claireho goto Fail4; 2775569331642446be05292e3e1f8a51218827168cdclaireho 2785569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort(); 2795569331642446be05292e3e1f8a51218827168cdclaireho 2805569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 2815569331642446be05292e3e1f8a51218827168cdclaireho 2825569331642446be05292e3e1f8a51218827168cdclaireho if ( new_offset ) 2835569331642446be05292e3e1f8a51218827168cdclaireho { 2845569331642446be05292e3e1f8a51218827168cdclaireho new_offset += base_offset; 2855569331642446be05292e3e1f8a51218827168cdclaireho 2865569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 2875569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 28857e6107a9d66a9a97b146def0ef38c010f954be6claireho ( error = _HB_OPEN_Load_Device( &vr->DeviceTables[VR_X_PLACEMENT_DEVICE], 2895569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 29057e6107a9d66a9a97b146def0ef38c010f954be6claireho goto Fail4; 2915569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 2925569331642446be05292e3e1f8a51218827168cdclaireho } 2935569331642446be05292e3e1f8a51218827168cdclaireho } 2945569331642446be05292e3e1f8a51218827168cdclaireho 2955569331642446be05292e3e1f8a51218827168cdclaireho if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE ) 2965569331642446be05292e3e1f8a51218827168cdclaireho { 2975569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 2985569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 2995569331642446be05292e3e1f8a51218827168cdclaireho 3005569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort(); 3015569331642446be05292e3e1f8a51218827168cdclaireho 3025569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 3035569331642446be05292e3e1f8a51218827168cdclaireho 3045569331642446be05292e3e1f8a51218827168cdclaireho if ( new_offset ) 3055569331642446be05292e3e1f8a51218827168cdclaireho { 3065569331642446be05292e3e1f8a51218827168cdclaireho new_offset += base_offset; 3075569331642446be05292e3e1f8a51218827168cdclaireho 3085569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 3095569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 31057e6107a9d66a9a97b146def0ef38c010f954be6claireho ( error = _HB_OPEN_Load_Device( &vr->DeviceTables[VR_Y_PLACEMENT_DEVICE], 3115569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 3125569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 3135569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 3145569331642446be05292e3e1f8a51218827168cdclaireho } 3155569331642446be05292e3e1f8a51218827168cdclaireho } 3165569331642446be05292e3e1f8a51218827168cdclaireho 3175569331642446be05292e3e1f8a51218827168cdclaireho if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE ) 3185569331642446be05292e3e1f8a51218827168cdclaireho { 3195569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 3205569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 3215569331642446be05292e3e1f8a51218827168cdclaireho 3225569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort(); 3235569331642446be05292e3e1f8a51218827168cdclaireho 3245569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 3255569331642446be05292e3e1f8a51218827168cdclaireho 3265569331642446be05292e3e1f8a51218827168cdclaireho if ( new_offset ) 3275569331642446be05292e3e1f8a51218827168cdclaireho { 3285569331642446be05292e3e1f8a51218827168cdclaireho new_offset += base_offset; 3295569331642446be05292e3e1f8a51218827168cdclaireho 3305569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 3315569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 33257e6107a9d66a9a97b146def0ef38c010f954be6claireho ( error = _HB_OPEN_Load_Device( &vr->DeviceTables[VR_X_ADVANCE_DEVICE], 3335569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 3345569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 3355569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 3365569331642446be05292e3e1f8a51218827168cdclaireho } 3375569331642446be05292e3e1f8a51218827168cdclaireho } 3385569331642446be05292e3e1f8a51218827168cdclaireho 3395569331642446be05292e3e1f8a51218827168cdclaireho if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE ) 3405569331642446be05292e3e1f8a51218827168cdclaireho { 3415569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 3425569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 3435569331642446be05292e3e1f8a51218827168cdclaireho 3445569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort(); 3455569331642446be05292e3e1f8a51218827168cdclaireho 3465569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 3475569331642446be05292e3e1f8a51218827168cdclaireho 3485569331642446be05292e3e1f8a51218827168cdclaireho if ( new_offset ) 3495569331642446be05292e3e1f8a51218827168cdclaireho { 3505569331642446be05292e3e1f8a51218827168cdclaireho new_offset += base_offset; 3515569331642446be05292e3e1f8a51218827168cdclaireho 3525569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 3535569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 35457e6107a9d66a9a97b146def0ef38c010f954be6claireho ( error = _HB_OPEN_Load_Device( &vr->DeviceTables[VR_Y_ADVANCE_DEVICE], 3555569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 3565569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 3575569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 3585569331642446be05292e3e1f8a51218827168cdclaireho } 3595569331642446be05292e3e1f8a51218827168cdclaireho } 3605569331642446be05292e3e1f8a51218827168cdclaireho 3615569331642446be05292e3e1f8a51218827168cdclaireho if ( format & HB_GPOS_FORMAT_HAVE_X_ID_PLACEMENT ) 3625569331642446be05292e3e1f8a51218827168cdclaireho { 3635569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 3645569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 3655569331642446be05292e3e1f8a51218827168cdclaireho 36657e6107a9d66a9a97b146def0ef38c010f954be6claireho#ifdef HB_SUPPORT_MULTIPLE_MASTER 3675569331642446be05292e3e1f8a51218827168cdclaireho vr->XIdPlacement = GET_UShort(); 36857e6107a9d66a9a97b146def0ef38c010f954be6claireho#else 36957e6107a9d66a9a97b146def0ef38c010f954be6claireho (void) GET_UShort(); 37057e6107a9d66a9a97b146def0ef38c010f954be6claireho#endif 3715569331642446be05292e3e1f8a51218827168cdclaireho 3725569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 3735569331642446be05292e3e1f8a51218827168cdclaireho } 37457e6107a9d66a9a97b146def0ef38c010f954be6claireho#ifdef HB_SUPPORT_MULTIPLE_MASTER 3755569331642446be05292e3e1f8a51218827168cdclaireho else 3765569331642446be05292e3e1f8a51218827168cdclaireho vr->XIdPlacement = 0; 37757e6107a9d66a9a97b146def0ef38c010f954be6claireho#endif 3785569331642446be05292e3e1f8a51218827168cdclaireho 3795569331642446be05292e3e1f8a51218827168cdclaireho if ( format & HB_GPOS_FORMAT_HAVE_Y_ID_PLACEMENT ) 3805569331642446be05292e3e1f8a51218827168cdclaireho { 3815569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 3825569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 3835569331642446be05292e3e1f8a51218827168cdclaireho 38457e6107a9d66a9a97b146def0ef38c010f954be6claireho#ifdef HB_SUPPORT_MULTIPLE_MASTER 3855569331642446be05292e3e1f8a51218827168cdclaireho vr->YIdPlacement = GET_UShort(); 38657e6107a9d66a9a97b146def0ef38c010f954be6claireho#else 38757e6107a9d66a9a97b146def0ef38c010f954be6claireho (void) GET_UShort(); 38857e6107a9d66a9a97b146def0ef38c010f954be6claireho#endif 3895569331642446be05292e3e1f8a51218827168cdclaireho 3905569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 3915569331642446be05292e3e1f8a51218827168cdclaireho } 39257e6107a9d66a9a97b146def0ef38c010f954be6claireho#ifdef HB_SUPPORT_MULTIPLE_MASTER 3935569331642446be05292e3e1f8a51218827168cdclaireho else 3945569331642446be05292e3e1f8a51218827168cdclaireho vr->YIdPlacement = 0; 39557e6107a9d66a9a97b146def0ef38c010f954be6claireho#endif 3965569331642446be05292e3e1f8a51218827168cdclaireho 3975569331642446be05292e3e1f8a51218827168cdclaireho if ( format & HB_GPOS_FORMAT_HAVE_X_ID_ADVANCE ) 3985569331642446be05292e3e1f8a51218827168cdclaireho { 3995569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 4005569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 4015569331642446be05292e3e1f8a51218827168cdclaireho 40257e6107a9d66a9a97b146def0ef38c010f954be6claireho#ifdef HB_SUPPORT_MULTIPLE_MASTER 4035569331642446be05292e3e1f8a51218827168cdclaireho vr->XIdAdvance = GET_UShort(); 40457e6107a9d66a9a97b146def0ef38c010f954be6claireho#else 40557e6107a9d66a9a97b146def0ef38c010f954be6claireho (void) GET_UShort(); 40657e6107a9d66a9a97b146def0ef38c010f954be6claireho#endif 4075569331642446be05292e3e1f8a51218827168cdclaireho 4085569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 4095569331642446be05292e3e1f8a51218827168cdclaireho } 41057e6107a9d66a9a97b146def0ef38c010f954be6claireho#ifdef HB_SUPPORT_MULTIPLE_MASTER 4115569331642446be05292e3e1f8a51218827168cdclaireho else 4125569331642446be05292e3e1f8a51218827168cdclaireho vr->XIdAdvance = 0; 41357e6107a9d66a9a97b146def0ef38c010f954be6claireho#endif 4145569331642446be05292e3e1f8a51218827168cdclaireho 4155569331642446be05292e3e1f8a51218827168cdclaireho if ( format & HB_GPOS_FORMAT_HAVE_Y_ID_ADVANCE ) 4165569331642446be05292e3e1f8a51218827168cdclaireho { 4175569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 4185569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 4195569331642446be05292e3e1f8a51218827168cdclaireho 42057e6107a9d66a9a97b146def0ef38c010f954be6claireho#ifdef HB_SUPPORT_MULTIPLE_MASTER 4215569331642446be05292e3e1f8a51218827168cdclaireho vr->YIdAdvance = GET_UShort(); 42257e6107a9d66a9a97b146def0ef38c010f954be6claireho#else 42357e6107a9d66a9a97b146def0ef38c010f954be6claireho (void) GET_UShort(); 42457e6107a9d66a9a97b146def0ef38c010f954be6claireho#endif 4255569331642446be05292e3e1f8a51218827168cdclaireho 4265569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 4275569331642446be05292e3e1f8a51218827168cdclaireho } 42857e6107a9d66a9a97b146def0ef38c010f954be6claireho#ifdef HB_SUPPORT_MULTIPLE_MASTER 4295569331642446be05292e3e1f8a51218827168cdclaireho else 4305569331642446be05292e3e1f8a51218827168cdclaireho vr->YIdAdvance = 0; 43157e6107a9d66a9a97b146def0ef38c010f954be6claireho#endif 4325569331642446be05292e3e1f8a51218827168cdclaireho 4335569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 4345569331642446be05292e3e1f8a51218827168cdclaireho 4355569331642446be05292e3e1f8a51218827168cdclairehoFail1: 43657e6107a9d66a9a97b146def0ef38c010f954be6claireho if ( vr->DeviceTables ) 43757e6107a9d66a9a97b146def0ef38c010f954be6claireho _HB_OPEN_Free_Device( vr->DeviceTables[VR_Y_ADVANCE_DEVICE] ); 4385569331642446be05292e3e1f8a51218827168cdclaireho 4395569331642446be05292e3e1f8a51218827168cdclairehoFail2: 44057e6107a9d66a9a97b146def0ef38c010f954be6claireho if ( vr->DeviceTables ) 44157e6107a9d66a9a97b146def0ef38c010f954be6claireho _HB_OPEN_Free_Device( vr->DeviceTables[VR_X_ADVANCE_DEVICE] ); 4425569331642446be05292e3e1f8a51218827168cdclaireho 4435569331642446be05292e3e1f8a51218827168cdclairehoFail3: 44457e6107a9d66a9a97b146def0ef38c010f954be6claireho if ( vr->DeviceTables ) 44557e6107a9d66a9a97b146def0ef38c010f954be6claireho _HB_OPEN_Free_Device( vr->DeviceTables[VR_Y_PLACEMENT_DEVICE] ); 44657e6107a9d66a9a97b146def0ef38c010f954be6claireho 44757e6107a9d66a9a97b146def0ef38c010f954be6clairehoFail4: 44857e6107a9d66a9a97b146def0ef38c010f954be6claireho FREE( vr->DeviceTables ); 4495569331642446be05292e3e1f8a51218827168cdclaireho return error; 4505569331642446be05292e3e1f8a51218827168cdclaireho} 4515569331642446be05292e3e1f8a51218827168cdclaireho 4525569331642446be05292e3e1f8a51218827168cdclaireho 4535569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_ValueRecord( HB_ValueRecord* vr, 4545569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort format ) 4555569331642446be05292e3e1f8a51218827168cdclaireho{ 4565569331642446be05292e3e1f8a51218827168cdclaireho if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE ) 45757e6107a9d66a9a97b146def0ef38c010f954be6claireho _HB_OPEN_Free_Device( vr->DeviceTables[VR_Y_ADVANCE_DEVICE] ); 4585569331642446be05292e3e1f8a51218827168cdclaireho if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE ) 45957e6107a9d66a9a97b146def0ef38c010f954be6claireho _HB_OPEN_Free_Device( vr->DeviceTables[VR_X_ADVANCE_DEVICE] ); 4605569331642446be05292e3e1f8a51218827168cdclaireho if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE ) 46157e6107a9d66a9a97b146def0ef38c010f954be6claireho _HB_OPEN_Free_Device( vr->DeviceTables[VR_Y_PLACEMENT_DEVICE] ); 4625569331642446be05292e3e1f8a51218827168cdclaireho if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT_DEVICE ) 46357e6107a9d66a9a97b146def0ef38c010f954be6claireho _HB_OPEN_Free_Device( vr->DeviceTables[VR_X_PLACEMENT_DEVICE] ); 46457e6107a9d66a9a97b146def0ef38c010f954be6claireho FREE( vr->DeviceTables ); 4655569331642446be05292e3e1f8a51218827168cdclaireho} 4665569331642446be05292e3e1f8a51218827168cdclaireho 4675569331642446be05292e3e1f8a51218827168cdclaireho 4685569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Get_ValueRecord( GPOS_Instance* gpi, 4695569331642446be05292e3e1f8a51218827168cdclaireho HB_ValueRecord* vr, 4705569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort format, 4715569331642446be05292e3e1f8a51218827168cdclaireho HB_Position gd ) 4725569331642446be05292e3e1f8a51218827168cdclaireho{ 4735569331642446be05292e3e1f8a51218827168cdclaireho HB_Short pixel_value; 4745569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error = HB_Err_Ok; 47557e6107a9d66a9a97b146def0ef38c010f954be6claireho#ifdef HB_SUPPORT_MULTIPLE_MASTER 4765569331642446be05292e3e1f8a51218827168cdclaireho HB_GPOSHeader* gpos = gpi->gpos; 47757e6107a9d66a9a97b146def0ef38c010f954be6claireho HB_Fixed value; 47857e6107a9d66a9a97b146def0ef38c010f954be6claireho#endif 4795569331642446be05292e3e1f8a51218827168cdclaireho 4805569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort x_ppem, y_ppem; 4815569331642446be05292e3e1f8a51218827168cdclaireho HB_16Dot16 x_scale, y_scale; 4825569331642446be05292e3e1f8a51218827168cdclaireho 4835569331642446be05292e3e1f8a51218827168cdclaireho 4845569331642446be05292e3e1f8a51218827168cdclaireho if ( !format ) 4855569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 4865569331642446be05292e3e1f8a51218827168cdclaireho 4875569331642446be05292e3e1f8a51218827168cdclaireho x_ppem = gpi->font->x_ppem; 4885569331642446be05292e3e1f8a51218827168cdclaireho y_ppem = gpi->font->y_ppem; 4895569331642446be05292e3e1f8a51218827168cdclaireho x_scale = gpi->font->x_scale; 4905569331642446be05292e3e1f8a51218827168cdclaireho y_scale = gpi->font->y_scale; 4915569331642446be05292e3e1f8a51218827168cdclaireho 4925569331642446be05292e3e1f8a51218827168cdclaireho /* design units -> fractional pixel */ 4935569331642446be05292e3e1f8a51218827168cdclaireho 4945569331642446be05292e3e1f8a51218827168cdclaireho if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT ) 4955569331642446be05292e3e1f8a51218827168cdclaireho gd->x_pos += x_scale * vr->XPlacement / 0x10000; 4965569331642446be05292e3e1f8a51218827168cdclaireho if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT ) 4975569331642446be05292e3e1f8a51218827168cdclaireho gd->y_pos += y_scale * vr->YPlacement / 0x10000; 4985569331642446be05292e3e1f8a51218827168cdclaireho if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE ) 4995569331642446be05292e3e1f8a51218827168cdclaireho gd->x_advance += x_scale * vr->XAdvance / 0x10000; 5005569331642446be05292e3e1f8a51218827168cdclaireho if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE ) 5015569331642446be05292e3e1f8a51218827168cdclaireho gd->y_advance += y_scale * vr->YAdvance / 0x10000; 5025569331642446be05292e3e1f8a51218827168cdclaireho 5035569331642446be05292e3e1f8a51218827168cdclaireho if ( !gpi->dvi ) 5045569331642446be05292e3e1f8a51218827168cdclaireho { 5055569331642446be05292e3e1f8a51218827168cdclaireho /* pixel -> fractional pixel */ 5065569331642446be05292e3e1f8a51218827168cdclaireho 5075569331642446be05292e3e1f8a51218827168cdclaireho if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT_DEVICE ) 5085569331642446be05292e3e1f8a51218827168cdclaireho { 50957e6107a9d66a9a97b146def0ef38c010f954be6claireho _HB_OPEN_Get_Device( vr->DeviceTables[VR_X_PLACEMENT_DEVICE], x_ppem, &pixel_value ); 5105569331642446be05292e3e1f8a51218827168cdclaireho gd->x_pos += pixel_value << 6; 5115569331642446be05292e3e1f8a51218827168cdclaireho } 5125569331642446be05292e3e1f8a51218827168cdclaireho if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE ) 5135569331642446be05292e3e1f8a51218827168cdclaireho { 51457e6107a9d66a9a97b146def0ef38c010f954be6claireho _HB_OPEN_Get_Device( vr->DeviceTables[VR_Y_PLACEMENT_DEVICE], y_ppem, &pixel_value ); 5155569331642446be05292e3e1f8a51218827168cdclaireho gd->y_pos += pixel_value << 6; 5165569331642446be05292e3e1f8a51218827168cdclaireho } 5175569331642446be05292e3e1f8a51218827168cdclaireho if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE ) 5185569331642446be05292e3e1f8a51218827168cdclaireho { 51957e6107a9d66a9a97b146def0ef38c010f954be6claireho _HB_OPEN_Get_Device( vr->DeviceTables[VR_X_ADVANCE_DEVICE], x_ppem, &pixel_value ); 5205569331642446be05292e3e1f8a51218827168cdclaireho gd->x_advance += pixel_value << 6; 5215569331642446be05292e3e1f8a51218827168cdclaireho } 5225569331642446be05292e3e1f8a51218827168cdclaireho if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE ) 5235569331642446be05292e3e1f8a51218827168cdclaireho { 52457e6107a9d66a9a97b146def0ef38c010f954be6claireho _HB_OPEN_Get_Device( vr->DeviceTables[VR_Y_ADVANCE_DEVICE], y_ppem, &pixel_value ); 5255569331642446be05292e3e1f8a51218827168cdclaireho gd->y_advance += pixel_value << 6; 5265569331642446be05292e3e1f8a51218827168cdclaireho } 5275569331642446be05292e3e1f8a51218827168cdclaireho } 5285569331642446be05292e3e1f8a51218827168cdclaireho 52957e6107a9d66a9a97b146def0ef38c010f954be6claireho#ifdef HB_SUPPORT_MULTIPLE_MASTER 5305569331642446be05292e3e1f8a51218827168cdclaireho /* values returned from mmfunc() are already in fractional pixels */ 5315569331642446be05292e3e1f8a51218827168cdclaireho 5325569331642446be05292e3e1f8a51218827168cdclaireho if ( format & HB_GPOS_FORMAT_HAVE_X_ID_PLACEMENT ) 5335569331642446be05292e3e1f8a51218827168cdclaireho { 5345569331642446be05292e3e1f8a51218827168cdclaireho error = (gpos->mmfunc)( gpi->font, vr->XIdPlacement, 5355569331642446be05292e3e1f8a51218827168cdclaireho &value, gpos->data ); 5365569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 5375569331642446be05292e3e1f8a51218827168cdclaireho return error; 5385569331642446be05292e3e1f8a51218827168cdclaireho gd->x_pos += value; 5395569331642446be05292e3e1f8a51218827168cdclaireho } 5405569331642446be05292e3e1f8a51218827168cdclaireho if ( format & HB_GPOS_FORMAT_HAVE_Y_ID_PLACEMENT ) 5415569331642446be05292e3e1f8a51218827168cdclaireho { 5425569331642446be05292e3e1f8a51218827168cdclaireho error = (gpos->mmfunc)( gpi->font, vr->YIdPlacement, 5435569331642446be05292e3e1f8a51218827168cdclaireho &value, gpos->data ); 5445569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 5455569331642446be05292e3e1f8a51218827168cdclaireho return error; 5465569331642446be05292e3e1f8a51218827168cdclaireho gd->y_pos += value; 5475569331642446be05292e3e1f8a51218827168cdclaireho } 5485569331642446be05292e3e1f8a51218827168cdclaireho if ( format & HB_GPOS_FORMAT_HAVE_X_ID_ADVANCE ) 5495569331642446be05292e3e1f8a51218827168cdclaireho { 5505569331642446be05292e3e1f8a51218827168cdclaireho error = (gpos->mmfunc)( gpi->font, vr->XIdAdvance, 5515569331642446be05292e3e1f8a51218827168cdclaireho &value, gpos->data ); 5525569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 5535569331642446be05292e3e1f8a51218827168cdclaireho return error; 5545569331642446be05292e3e1f8a51218827168cdclaireho gd->x_advance += value; 5555569331642446be05292e3e1f8a51218827168cdclaireho } 5565569331642446be05292e3e1f8a51218827168cdclaireho if ( format & HB_GPOS_FORMAT_HAVE_Y_ID_ADVANCE ) 5575569331642446be05292e3e1f8a51218827168cdclaireho { 5585569331642446be05292e3e1f8a51218827168cdclaireho error = (gpos->mmfunc)( gpi->font, vr->YIdAdvance, 5595569331642446be05292e3e1f8a51218827168cdclaireho &value, gpos->data ); 5605569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 5615569331642446be05292e3e1f8a51218827168cdclaireho return error; 5625569331642446be05292e3e1f8a51218827168cdclaireho gd->y_advance += value; 5635569331642446be05292e3e1f8a51218827168cdclaireho } 56457e6107a9d66a9a97b146def0ef38c010f954be6claireho#endif 5655569331642446be05292e3e1f8a51218827168cdclaireho 5665569331642446be05292e3e1f8a51218827168cdclaireho return error; 5675569331642446be05292e3e1f8a51218827168cdclaireho} 5685569331642446be05292e3e1f8a51218827168cdclaireho 5695569331642446be05292e3e1f8a51218827168cdclaireho 5705569331642446be05292e3e1f8a51218827168cdclaireho/* AnchorFormat1 */ 5715569331642446be05292e3e1f8a51218827168cdclaireho/* AnchorFormat2 */ 5725569331642446be05292e3e1f8a51218827168cdclaireho/* AnchorFormat3 */ 5735569331642446be05292e3e1f8a51218827168cdclaireho/* AnchorFormat4 */ 5745569331642446be05292e3e1f8a51218827168cdclaireho 5755569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_Anchor( HB_Anchor* an, 5765569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 5775569331642446be05292e3e1f8a51218827168cdclaireho{ 5785569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 5795569331642446be05292e3e1f8a51218827168cdclaireho 5805569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 5815569331642446be05292e3e1f8a51218827168cdclaireho 5825569331642446be05292e3e1f8a51218827168cdclaireho 5835569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 5845569331642446be05292e3e1f8a51218827168cdclaireho 5855569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 5865569331642446be05292e3e1f8a51218827168cdclaireho return error; 5875569331642446be05292e3e1f8a51218827168cdclaireho 5885569331642446be05292e3e1f8a51218827168cdclaireho an->PosFormat = GET_UShort(); 5895569331642446be05292e3e1f8a51218827168cdclaireho 5905569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 5915569331642446be05292e3e1f8a51218827168cdclaireho 5925569331642446be05292e3e1f8a51218827168cdclaireho switch ( an->PosFormat ) 5935569331642446be05292e3e1f8a51218827168cdclaireho { 5945569331642446be05292e3e1f8a51218827168cdclaireho case 1: 5955569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 4L ) ) 5965569331642446be05292e3e1f8a51218827168cdclaireho return error; 5975569331642446be05292e3e1f8a51218827168cdclaireho 5985569331642446be05292e3e1f8a51218827168cdclaireho an->af.af1.XCoordinate = GET_Short(); 5995569331642446be05292e3e1f8a51218827168cdclaireho an->af.af1.YCoordinate = GET_Short(); 6005569331642446be05292e3e1f8a51218827168cdclaireho 6015569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 6025569331642446be05292e3e1f8a51218827168cdclaireho break; 6035569331642446be05292e3e1f8a51218827168cdclaireho 6045569331642446be05292e3e1f8a51218827168cdclaireho case 2: 6055569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 6L ) ) 6065569331642446be05292e3e1f8a51218827168cdclaireho return error; 6075569331642446be05292e3e1f8a51218827168cdclaireho 6085569331642446be05292e3e1f8a51218827168cdclaireho an->af.af2.XCoordinate = GET_Short(); 6095569331642446be05292e3e1f8a51218827168cdclaireho an->af.af2.YCoordinate = GET_Short(); 6105569331642446be05292e3e1f8a51218827168cdclaireho an->af.af2.AnchorPoint = GET_UShort(); 6115569331642446be05292e3e1f8a51218827168cdclaireho 6125569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 6135569331642446be05292e3e1f8a51218827168cdclaireho break; 6145569331642446be05292e3e1f8a51218827168cdclaireho 6155569331642446be05292e3e1f8a51218827168cdclaireho case 3: 6165569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 6L ) ) 6175569331642446be05292e3e1f8a51218827168cdclaireho return error; 6185569331642446be05292e3e1f8a51218827168cdclaireho 6195569331642446be05292e3e1f8a51218827168cdclaireho an->af.af3.XCoordinate = GET_Short(); 6205569331642446be05292e3e1f8a51218827168cdclaireho an->af.af3.YCoordinate = GET_Short(); 6215569331642446be05292e3e1f8a51218827168cdclaireho 6225569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort(); 6235569331642446be05292e3e1f8a51218827168cdclaireho 6245569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 6255569331642446be05292e3e1f8a51218827168cdclaireho 6265569331642446be05292e3e1f8a51218827168cdclaireho if ( new_offset ) 6275569331642446be05292e3e1f8a51218827168cdclaireho { 62857e6107a9d66a9a97b146def0ef38c010f954be6claireho if ( ALLOC_ARRAY( an->af.af3.DeviceTables, 2, HB_Device ) ) 62957e6107a9d66a9a97b146def0ef38c010f954be6claireho return error; 63057e6107a9d66a9a97b146def0ef38c010f954be6claireho 63157e6107a9d66a9a97b146def0ef38c010f954be6claireho an->af.af3.DeviceTables[AF3_X_DEVICE_TABLE] = 0; 63257e6107a9d66a9a97b146def0ef38c010f954be6claireho an->af.af3.DeviceTables[AF3_Y_DEVICE_TABLE] = 0; 63357e6107a9d66a9a97b146def0ef38c010f954be6claireho 6345569331642446be05292e3e1f8a51218827168cdclaireho new_offset += base_offset; 6355569331642446be05292e3e1f8a51218827168cdclaireho 6365569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 6375569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 63857e6107a9d66a9a97b146def0ef38c010f954be6claireho ( error = _HB_OPEN_Load_Device( &an->af.af3.DeviceTables[AF3_X_DEVICE_TABLE], 6395569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 64057e6107a9d66a9a97b146def0ef38c010f954be6claireho goto Fail2; 6415569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 6425569331642446be05292e3e1f8a51218827168cdclaireho } 6435569331642446be05292e3e1f8a51218827168cdclaireho 6445569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 6455569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 6465569331642446be05292e3e1f8a51218827168cdclaireho 6475569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort(); 6485569331642446be05292e3e1f8a51218827168cdclaireho 6495569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 6505569331642446be05292e3e1f8a51218827168cdclaireho 6515569331642446be05292e3e1f8a51218827168cdclaireho if ( new_offset ) 6525569331642446be05292e3e1f8a51218827168cdclaireho { 65357e6107a9d66a9a97b146def0ef38c010f954be6claireho if ( !an->af.af3.DeviceTables ) 65457e6107a9d66a9a97b146def0ef38c010f954be6claireho { 65557e6107a9d66a9a97b146def0ef38c010f954be6claireho if ( ALLOC_ARRAY( an->af.af3.DeviceTables, 2, HB_Device ) ) 65657e6107a9d66a9a97b146def0ef38c010f954be6claireho return error; 65757e6107a9d66a9a97b146def0ef38c010f954be6claireho 65857e6107a9d66a9a97b146def0ef38c010f954be6claireho an->af.af3.DeviceTables[AF3_X_DEVICE_TABLE] = 0; 65957e6107a9d66a9a97b146def0ef38c010f954be6claireho an->af.af3.DeviceTables[AF3_Y_DEVICE_TABLE] = 0; 66057e6107a9d66a9a97b146def0ef38c010f954be6claireho } 66157e6107a9d66a9a97b146def0ef38c010f954be6claireho 6625569331642446be05292e3e1f8a51218827168cdclaireho new_offset += base_offset; 6635569331642446be05292e3e1f8a51218827168cdclaireho 6645569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 6655569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 66657e6107a9d66a9a97b146def0ef38c010f954be6claireho ( error = _HB_OPEN_Load_Device( &an->af.af3.DeviceTables[AF3_Y_DEVICE_TABLE], 6675569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 6685569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 6695569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 6705569331642446be05292e3e1f8a51218827168cdclaireho } 6715569331642446be05292e3e1f8a51218827168cdclaireho break; 6725569331642446be05292e3e1f8a51218827168cdclaireho 6735569331642446be05292e3e1f8a51218827168cdclaireho case 4: 6745569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 4L ) ) 6755569331642446be05292e3e1f8a51218827168cdclaireho return error; 6765569331642446be05292e3e1f8a51218827168cdclaireho 67757e6107a9d66a9a97b146def0ef38c010f954be6claireho#ifdef HB_SUPPORT_MULTIPLE_MASTER 6785569331642446be05292e3e1f8a51218827168cdclaireho an->af.af4.XIdAnchor = GET_UShort(); 6795569331642446be05292e3e1f8a51218827168cdclaireho an->af.af4.YIdAnchor = GET_UShort(); 68057e6107a9d66a9a97b146def0ef38c010f954be6claireho#else 68157e6107a9d66a9a97b146def0ef38c010f954be6claireho (void) GET_UShort(); 68257e6107a9d66a9a97b146def0ef38c010f954be6claireho (void) GET_UShort(); 68357e6107a9d66a9a97b146def0ef38c010f954be6claireho#endif 6845569331642446be05292e3e1f8a51218827168cdclaireho 6855569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 6865569331642446be05292e3e1f8a51218827168cdclaireho break; 6875569331642446be05292e3e1f8a51218827168cdclaireho 6885569331642446be05292e3e1f8a51218827168cdclaireho default: 6895569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable_Format); 6905569331642446be05292e3e1f8a51218827168cdclaireho } 6915569331642446be05292e3e1f8a51218827168cdclaireho 6925569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 6935569331642446be05292e3e1f8a51218827168cdclaireho 6945569331642446be05292e3e1f8a51218827168cdclairehoFail: 69557e6107a9d66a9a97b146def0ef38c010f954be6claireho if ( an->af.af3.DeviceTables ) 69657e6107a9d66a9a97b146def0ef38c010f954be6claireho _HB_OPEN_Free_Device( an->af.af3.DeviceTables[AF3_X_DEVICE_TABLE] ); 69757e6107a9d66a9a97b146def0ef38c010f954be6claireho 69857e6107a9d66a9a97b146def0ef38c010f954be6clairehoFail2: 69957e6107a9d66a9a97b146def0ef38c010f954be6claireho FREE( an->af.af3.DeviceTables ); 7005569331642446be05292e3e1f8a51218827168cdclaireho return error; 7015569331642446be05292e3e1f8a51218827168cdclaireho} 7025569331642446be05292e3e1f8a51218827168cdclaireho 7035569331642446be05292e3e1f8a51218827168cdclaireho 7045569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_Anchor( HB_Anchor* an) 7055569331642446be05292e3e1f8a51218827168cdclaireho{ 70657e6107a9d66a9a97b146def0ef38c010f954be6claireho if ( an->PosFormat == 3 && an->af.af3.DeviceTables ) 7075569331642446be05292e3e1f8a51218827168cdclaireho { 70857e6107a9d66a9a97b146def0ef38c010f954be6claireho _HB_OPEN_Free_Device( an->af.af3.DeviceTables[AF3_X_DEVICE_TABLE] ); 70957e6107a9d66a9a97b146def0ef38c010f954be6claireho _HB_OPEN_Free_Device( an->af.af3.DeviceTables[AF3_Y_DEVICE_TABLE] ); 71057e6107a9d66a9a97b146def0ef38c010f954be6claireho FREE( an->af.af3.DeviceTables ); 7115569331642446be05292e3e1f8a51218827168cdclaireho } 7125569331642446be05292e3e1f8a51218827168cdclaireho} 7135569331642446be05292e3e1f8a51218827168cdclaireho 7145569331642446be05292e3e1f8a51218827168cdclaireho 7155569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Get_Anchor( GPOS_Instance* gpi, 7165569331642446be05292e3e1f8a51218827168cdclaireho HB_Anchor* an, 7175569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort glyph_index, 7185569331642446be05292e3e1f8a51218827168cdclaireho HB_Fixed* x_value, 7195569331642446be05292e3e1f8a51218827168cdclaireho HB_Fixed* y_value ) 7205569331642446be05292e3e1f8a51218827168cdclaireho{ 7215569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error = HB_Err_Ok; 7225569331642446be05292e3e1f8a51218827168cdclaireho 72357e6107a9d66a9a97b146def0ef38c010f954be6claireho#ifdef HB_SUPPORT_MULTIPLE_MASTER 7245569331642446be05292e3e1f8a51218827168cdclaireho HB_GPOSHeader* gpos = gpi->gpos; 72557e6107a9d66a9a97b146def0ef38c010f954be6claireho#endif 7265569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort ap; 7275569331642446be05292e3e1f8a51218827168cdclaireho 7285569331642446be05292e3e1f8a51218827168cdclaireho HB_Short pixel_value; 7295569331642446be05292e3e1f8a51218827168cdclaireho 7305569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort x_ppem, y_ppem; 7315569331642446be05292e3e1f8a51218827168cdclaireho HB_16Dot16 x_scale, y_scale; 7325569331642446be05292e3e1f8a51218827168cdclaireho 7335569331642446be05292e3e1f8a51218827168cdclaireho 7345569331642446be05292e3e1f8a51218827168cdclaireho x_ppem = gpi->font->x_ppem; 7355569331642446be05292e3e1f8a51218827168cdclaireho y_ppem = gpi->font->y_ppem; 7365569331642446be05292e3e1f8a51218827168cdclaireho x_scale = gpi->font->x_scale; 7375569331642446be05292e3e1f8a51218827168cdclaireho y_scale = gpi->font->y_scale; 7385569331642446be05292e3e1f8a51218827168cdclaireho 7395569331642446be05292e3e1f8a51218827168cdclaireho switch ( an->PosFormat ) 7405569331642446be05292e3e1f8a51218827168cdclaireho { 7415569331642446be05292e3e1f8a51218827168cdclaireho case 0: 7425569331642446be05292e3e1f8a51218827168cdclaireho /* The special case of an empty AnchorTable */ 7435569331642446be05292e3e1f8a51218827168cdclaireho default: 7445569331642446be05292e3e1f8a51218827168cdclaireho 7455569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 7465569331642446be05292e3e1f8a51218827168cdclaireho 7475569331642446be05292e3e1f8a51218827168cdclaireho case 1: 7485569331642446be05292e3e1f8a51218827168cdclaireho *x_value = x_scale * an->af.af1.XCoordinate / 0x10000; 7495569331642446be05292e3e1f8a51218827168cdclaireho *y_value = y_scale * an->af.af1.YCoordinate / 0x10000; 7505569331642446be05292e3e1f8a51218827168cdclaireho break; 7515569331642446be05292e3e1f8a51218827168cdclaireho 7525569331642446be05292e3e1f8a51218827168cdclaireho case 2: 7535569331642446be05292e3e1f8a51218827168cdclaireho if ( !gpi->dvi ) 7545569331642446be05292e3e1f8a51218827168cdclaireho { 7555569331642446be05292e3e1f8a51218827168cdclaireho hb_uint32 n_points = 0; 7565569331642446be05292e3e1f8a51218827168cdclaireho ap = an->af.af2.AnchorPoint; 7575569331642446be05292e3e1f8a51218827168cdclaireho if (!gpi->font->klass->getPointInOutline) 7585569331642446be05292e3e1f8a51218827168cdclaireho goto no_contour_point; 7595569331642446be05292e3e1f8a51218827168cdclaireho error = gpi->font->klass->getPointInOutline(gpi->font, glyph_index, gpi->load_flags, ap, x_value, y_value, &n_points); 7605569331642446be05292e3e1f8a51218827168cdclaireho if (error) 7615569331642446be05292e3e1f8a51218827168cdclaireho return error; 7625569331642446be05292e3e1f8a51218827168cdclaireho /* if n_points is set to zero, we use the design coordinate value pair. 7635569331642446be05292e3e1f8a51218827168cdclaireho * This can happen e.g. for sbit glyphs. */ 7645569331642446be05292e3e1f8a51218827168cdclaireho if (!n_points) 7655569331642446be05292e3e1f8a51218827168cdclaireho goto no_contour_point; 7665569331642446be05292e3e1f8a51218827168cdclaireho } 7675569331642446be05292e3e1f8a51218827168cdclaireho else 7685569331642446be05292e3e1f8a51218827168cdclaireho { 7695569331642446be05292e3e1f8a51218827168cdclaireho no_contour_point: 7705569331642446be05292e3e1f8a51218827168cdclaireho *x_value = x_scale * an->af.af3.XCoordinate / 0x10000; 7715569331642446be05292e3e1f8a51218827168cdclaireho *y_value = y_scale * an->af.af3.YCoordinate / 0x10000; 7725569331642446be05292e3e1f8a51218827168cdclaireho } 7735569331642446be05292e3e1f8a51218827168cdclaireho break; 7745569331642446be05292e3e1f8a51218827168cdclaireho 7755569331642446be05292e3e1f8a51218827168cdclaireho case 3: 7765569331642446be05292e3e1f8a51218827168cdclaireho if ( !gpi->dvi ) 7775569331642446be05292e3e1f8a51218827168cdclaireho { 77857e6107a9d66a9a97b146def0ef38c010f954be6claireho _HB_OPEN_Get_Device( an->af.af3.DeviceTables[AF3_X_DEVICE_TABLE], x_ppem, &pixel_value ); 7795569331642446be05292e3e1f8a51218827168cdclaireho *x_value = pixel_value << 6; 78057e6107a9d66a9a97b146def0ef38c010f954be6claireho _HB_OPEN_Get_Device( an->af.af3.DeviceTables[AF3_Y_DEVICE_TABLE], y_ppem, &pixel_value ); 7815569331642446be05292e3e1f8a51218827168cdclaireho *y_value = pixel_value << 6; 7825569331642446be05292e3e1f8a51218827168cdclaireho } 7835569331642446be05292e3e1f8a51218827168cdclaireho else 7845569331642446be05292e3e1f8a51218827168cdclaireho *x_value = *y_value = 0; 7855569331642446be05292e3e1f8a51218827168cdclaireho 7865569331642446be05292e3e1f8a51218827168cdclaireho *x_value += x_scale * an->af.af3.XCoordinate / 0x10000; 7875569331642446be05292e3e1f8a51218827168cdclaireho *y_value += y_scale * an->af.af3.YCoordinate / 0x10000; 7885569331642446be05292e3e1f8a51218827168cdclaireho break; 7895569331642446be05292e3e1f8a51218827168cdclaireho 7905569331642446be05292e3e1f8a51218827168cdclaireho case 4: 79157e6107a9d66a9a97b146def0ef38c010f954be6claireho#ifdef HB_SUPPORT_MULTIPLE_MASTER 7925569331642446be05292e3e1f8a51218827168cdclaireho error = (gpos->mmfunc)( gpi->font, an->af.af4.XIdAnchor, 7935569331642446be05292e3e1f8a51218827168cdclaireho x_value, gpos->data ); 7945569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 7955569331642446be05292e3e1f8a51218827168cdclaireho return error; 7965569331642446be05292e3e1f8a51218827168cdclaireho 7975569331642446be05292e3e1f8a51218827168cdclaireho error = (gpos->mmfunc)( gpi->font, an->af.af4.YIdAnchor, 7985569331642446be05292e3e1f8a51218827168cdclaireho y_value, gpos->data ); 7995569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 8005569331642446be05292e3e1f8a51218827168cdclaireho return error; 8015569331642446be05292e3e1f8a51218827168cdclaireho break; 80257e6107a9d66a9a97b146def0ef38c010f954be6claireho#else 80357e6107a9d66a9a97b146def0ef38c010f954be6claireho return ERR(HB_Err_Not_Covered); 80457e6107a9d66a9a97b146def0ef38c010f954be6claireho#endif 8055569331642446be05292e3e1f8a51218827168cdclaireho } 8065569331642446be05292e3e1f8a51218827168cdclaireho 8075569331642446be05292e3e1f8a51218827168cdclaireho return error; 8085569331642446be05292e3e1f8a51218827168cdclaireho} 8095569331642446be05292e3e1f8a51218827168cdclaireho 8105569331642446be05292e3e1f8a51218827168cdclaireho 8115569331642446be05292e3e1f8a51218827168cdclaireho/* MarkArray */ 8125569331642446be05292e3e1f8a51218827168cdclaireho 8135569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_MarkArray ( HB_MarkArray* ma, 8145569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 8155569331642446be05292e3e1f8a51218827168cdclaireho{ 8165569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 8175569331642446be05292e3e1f8a51218827168cdclaireho 8185569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, m, count; 8195569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 8205569331642446be05292e3e1f8a51218827168cdclaireho 8215569331642446be05292e3e1f8a51218827168cdclaireho HB_MarkRecord* mr; 8225569331642446be05292e3e1f8a51218827168cdclaireho 8235569331642446be05292e3e1f8a51218827168cdclaireho 8245569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 8255569331642446be05292e3e1f8a51218827168cdclaireho 8265569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 8275569331642446be05292e3e1f8a51218827168cdclaireho return error; 8285569331642446be05292e3e1f8a51218827168cdclaireho 8295569331642446be05292e3e1f8a51218827168cdclaireho count = ma->MarkCount = GET_UShort(); 8305569331642446be05292e3e1f8a51218827168cdclaireho 8315569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 8325569331642446be05292e3e1f8a51218827168cdclaireho 8335569331642446be05292e3e1f8a51218827168cdclaireho ma->MarkRecord = NULL; 8345569331642446be05292e3e1f8a51218827168cdclaireho 8355569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( ma->MarkRecord, count, HB_MarkRecord ) ) 8365569331642446be05292e3e1f8a51218827168cdclaireho return error; 8375569331642446be05292e3e1f8a51218827168cdclaireho 8385569331642446be05292e3e1f8a51218827168cdclaireho mr = ma->MarkRecord; 8395569331642446be05292e3e1f8a51218827168cdclaireho 8405569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 8415569331642446be05292e3e1f8a51218827168cdclaireho { 8425569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 4L ) ) 8435569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 8445569331642446be05292e3e1f8a51218827168cdclaireho 8455569331642446be05292e3e1f8a51218827168cdclaireho mr[n].Class = GET_UShort(); 8465569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 8475569331642446be05292e3e1f8a51218827168cdclaireho 8485569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 8495569331642446be05292e3e1f8a51218827168cdclaireho 8505569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 8515569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 8525569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_Anchor( &mr[n].MarkAnchor, stream ) ) != HB_Err_Ok ) 8535569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 8545569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 8555569331642446be05292e3e1f8a51218827168cdclaireho } 8565569331642446be05292e3e1f8a51218827168cdclaireho 8575569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 8585569331642446be05292e3e1f8a51218827168cdclaireho 8595569331642446be05292e3e1f8a51218827168cdclairehoFail: 8605569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; m++ ) 8615569331642446be05292e3e1f8a51218827168cdclaireho Free_Anchor( &mr[m].MarkAnchor ); 8625569331642446be05292e3e1f8a51218827168cdclaireho 8635569331642446be05292e3e1f8a51218827168cdclaireho FREE( mr ); 8645569331642446be05292e3e1f8a51218827168cdclaireho return error; 8655569331642446be05292e3e1f8a51218827168cdclaireho} 8665569331642446be05292e3e1f8a51218827168cdclaireho 8675569331642446be05292e3e1f8a51218827168cdclaireho 8685569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_MarkArray( HB_MarkArray* ma ) 8695569331642446be05292e3e1f8a51218827168cdclaireho{ 8705569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 8715569331642446be05292e3e1f8a51218827168cdclaireho 8725569331642446be05292e3e1f8a51218827168cdclaireho HB_MarkRecord* mr; 8735569331642446be05292e3e1f8a51218827168cdclaireho 8745569331642446be05292e3e1f8a51218827168cdclaireho 8755569331642446be05292e3e1f8a51218827168cdclaireho if ( ma->MarkRecord ) 8765569331642446be05292e3e1f8a51218827168cdclaireho { 8775569331642446be05292e3e1f8a51218827168cdclaireho count = ma->MarkCount; 8785569331642446be05292e3e1f8a51218827168cdclaireho mr = ma->MarkRecord; 8795569331642446be05292e3e1f8a51218827168cdclaireho 8805569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 8815569331642446be05292e3e1f8a51218827168cdclaireho Free_Anchor( &mr[n].MarkAnchor ); 8825569331642446be05292e3e1f8a51218827168cdclaireho 8835569331642446be05292e3e1f8a51218827168cdclaireho FREE( mr ); 8845569331642446be05292e3e1f8a51218827168cdclaireho } 8855569331642446be05292e3e1f8a51218827168cdclaireho} 8865569331642446be05292e3e1f8a51218827168cdclaireho 8875569331642446be05292e3e1f8a51218827168cdclaireho 8885569331642446be05292e3e1f8a51218827168cdclaireho/* LookupType 1 */ 8895569331642446be05292e3e1f8a51218827168cdclaireho 8905569331642446be05292e3e1f8a51218827168cdclaireho/* SinglePosFormat1 */ 8915569331642446be05292e3e1f8a51218827168cdclaireho/* SinglePosFormat2 */ 8925569331642446be05292e3e1f8a51218827168cdclaireho 8935569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_SinglePos( HB_GPOS_SubTable* st, 8945569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 8955569331642446be05292e3e1f8a51218827168cdclaireho{ 8965569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 8975569331642446be05292e3e1f8a51218827168cdclaireho HB_SinglePos* sp = &st->single; 8985569331642446be05292e3e1f8a51218827168cdclaireho 8995569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, m, count, format; 9005569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 9015569331642446be05292e3e1f8a51218827168cdclaireho 9025569331642446be05292e3e1f8a51218827168cdclaireho HB_ValueRecord* vr; 9035569331642446be05292e3e1f8a51218827168cdclaireho 9045569331642446be05292e3e1f8a51218827168cdclaireho 9055569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 9065569331642446be05292e3e1f8a51218827168cdclaireho 9075569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 6L ) ) 9085569331642446be05292e3e1f8a51218827168cdclaireho return error; 9095569331642446be05292e3e1f8a51218827168cdclaireho 9105569331642446be05292e3e1f8a51218827168cdclaireho sp->PosFormat = GET_UShort(); 9115569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 9125569331642446be05292e3e1f8a51218827168cdclaireho 9135569331642446be05292e3e1f8a51218827168cdclaireho format = sp->ValueFormat = GET_UShort(); 9145569331642446be05292e3e1f8a51218827168cdclaireho 9155569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 9165569331642446be05292e3e1f8a51218827168cdclaireho 9175569331642446be05292e3e1f8a51218827168cdclaireho if ( !format ) 9185569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable); 9195569331642446be05292e3e1f8a51218827168cdclaireho 9205569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 9215569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 9225569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &sp->Coverage, stream ) ) != HB_Err_Ok ) 9235569331642446be05292e3e1f8a51218827168cdclaireho return error; 9245569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 9255569331642446be05292e3e1f8a51218827168cdclaireho 9265569331642446be05292e3e1f8a51218827168cdclaireho switch ( sp->PosFormat ) 9275569331642446be05292e3e1f8a51218827168cdclaireho { 9285569331642446be05292e3e1f8a51218827168cdclaireho case 1: 9295569331642446be05292e3e1f8a51218827168cdclaireho error = Load_ValueRecord( &sp->spf.spf1.Value, format, 9305569331642446be05292e3e1f8a51218827168cdclaireho base_offset, stream ); 9315569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 9325569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 9335569331642446be05292e3e1f8a51218827168cdclaireho break; 9345569331642446be05292e3e1f8a51218827168cdclaireho 9355569331642446be05292e3e1f8a51218827168cdclaireho case 2: 9365569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 9375569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 9385569331642446be05292e3e1f8a51218827168cdclaireho 9395569331642446be05292e3e1f8a51218827168cdclaireho count = sp->spf.spf2.ValueCount = GET_UShort(); 9405569331642446be05292e3e1f8a51218827168cdclaireho 9415569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 9425569331642446be05292e3e1f8a51218827168cdclaireho 9435569331642446be05292e3e1f8a51218827168cdclaireho sp->spf.spf2.Value = NULL; 9445569331642446be05292e3e1f8a51218827168cdclaireho 9455569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( sp->spf.spf2.Value, count, HB_ValueRecord ) ) 9465569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 9475569331642446be05292e3e1f8a51218827168cdclaireho 9485569331642446be05292e3e1f8a51218827168cdclaireho vr = sp->spf.spf2.Value; 9495569331642446be05292e3e1f8a51218827168cdclaireho 9505569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 9515569331642446be05292e3e1f8a51218827168cdclaireho { 9525569331642446be05292e3e1f8a51218827168cdclaireho error = Load_ValueRecord( &vr[n], format, base_offset, stream ); 9535569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 9545569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 9555569331642446be05292e3e1f8a51218827168cdclaireho } 9565569331642446be05292e3e1f8a51218827168cdclaireho break; 9575569331642446be05292e3e1f8a51218827168cdclaireho 9585569331642446be05292e3e1f8a51218827168cdclaireho default: 9595569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable_Format); 9605569331642446be05292e3e1f8a51218827168cdclaireho } 9615569331642446be05292e3e1f8a51218827168cdclaireho 9625569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 9635569331642446be05292e3e1f8a51218827168cdclaireho 9645569331642446be05292e3e1f8a51218827168cdclairehoFail1: 9655569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; m++ ) 9665569331642446be05292e3e1f8a51218827168cdclaireho Free_ValueRecord( &vr[m], format ); 9675569331642446be05292e3e1f8a51218827168cdclaireho 9685569331642446be05292e3e1f8a51218827168cdclaireho FREE( vr ); 9695569331642446be05292e3e1f8a51218827168cdclaireho 9705569331642446be05292e3e1f8a51218827168cdclairehoFail2: 9715569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &sp->Coverage ); 9725569331642446be05292e3e1f8a51218827168cdclaireho return error; 9735569331642446be05292e3e1f8a51218827168cdclaireho} 9745569331642446be05292e3e1f8a51218827168cdclaireho 9755569331642446be05292e3e1f8a51218827168cdclaireho 9765569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_SinglePos( HB_GPOS_SubTable* st ) 9775569331642446be05292e3e1f8a51218827168cdclaireho{ 9785569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count, format; 9795569331642446be05292e3e1f8a51218827168cdclaireho HB_SinglePos* sp = &st->single; 9805569331642446be05292e3e1f8a51218827168cdclaireho 9815569331642446be05292e3e1f8a51218827168cdclaireho HB_ValueRecord* v; 9825569331642446be05292e3e1f8a51218827168cdclaireho 9835569331642446be05292e3e1f8a51218827168cdclaireho 9845569331642446be05292e3e1f8a51218827168cdclaireho format = sp->ValueFormat; 9855569331642446be05292e3e1f8a51218827168cdclaireho 9865569331642446be05292e3e1f8a51218827168cdclaireho switch ( sp->PosFormat ) 9875569331642446be05292e3e1f8a51218827168cdclaireho { 9885569331642446be05292e3e1f8a51218827168cdclaireho case 1: 9895569331642446be05292e3e1f8a51218827168cdclaireho Free_ValueRecord( &sp->spf.spf1.Value, format ); 9905569331642446be05292e3e1f8a51218827168cdclaireho break; 9915569331642446be05292e3e1f8a51218827168cdclaireho 9925569331642446be05292e3e1f8a51218827168cdclaireho case 2: 9935569331642446be05292e3e1f8a51218827168cdclaireho if ( sp->spf.spf2.Value ) 9945569331642446be05292e3e1f8a51218827168cdclaireho { 9955569331642446be05292e3e1f8a51218827168cdclaireho count = sp->spf.spf2.ValueCount; 9965569331642446be05292e3e1f8a51218827168cdclaireho v = sp->spf.spf2.Value; 9975569331642446be05292e3e1f8a51218827168cdclaireho 9985569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 9995569331642446be05292e3e1f8a51218827168cdclaireho Free_ValueRecord( &v[n], format ); 10005569331642446be05292e3e1f8a51218827168cdclaireho 10015569331642446be05292e3e1f8a51218827168cdclaireho FREE( v ); 10025569331642446be05292e3e1f8a51218827168cdclaireho } 10035569331642446be05292e3e1f8a51218827168cdclaireho break; 10045569331642446be05292e3e1f8a51218827168cdclaireho default: 10055569331642446be05292e3e1f8a51218827168cdclaireho break; 10065569331642446be05292e3e1f8a51218827168cdclaireho } 10075569331642446be05292e3e1f8a51218827168cdclaireho 10085569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &sp->Coverage ); 10095569331642446be05292e3e1f8a51218827168cdclaireho} 10105569331642446be05292e3e1f8a51218827168cdclaireho 10115569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Lookup_SinglePos( GPOS_Instance* gpi, 10125569331642446be05292e3e1f8a51218827168cdclaireho HB_GPOS_SubTable* st, 10135569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 10145569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort flags, 10155569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 10165569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 10175569331642446be05292e3e1f8a51218827168cdclaireho{ 10185569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort index, property; 10195569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 10205569331642446be05292e3e1f8a51218827168cdclaireho HB_GPOSHeader* gpos = gpi->gpos; 10215569331642446be05292e3e1f8a51218827168cdclaireho HB_SinglePos* sp = &st->single; 10225569331642446be05292e3e1f8a51218827168cdclaireho 10235569331642446be05292e3e1f8a51218827168cdclaireho HB_UNUSED(nesting_level); 10245569331642446be05292e3e1f8a51218827168cdclaireho 10255569331642446be05292e3e1f8a51218827168cdclaireho if ( context_length != 0xFFFF && context_length < 1 ) 10265569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 10275569331642446be05292e3e1f8a51218827168cdclaireho 10285569331642446be05292e3e1f8a51218827168cdclaireho if ( CHECK_Property( gpos->gdef, IN_CURITEM(), flags, &property ) ) 10295569331642446be05292e3e1f8a51218827168cdclaireho return error; 10305569331642446be05292e3e1f8a51218827168cdclaireho 10315569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &sp->Coverage, IN_CURGLYPH(), &index ); 10325569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 10335569331642446be05292e3e1f8a51218827168cdclaireho return error; 10345569331642446be05292e3e1f8a51218827168cdclaireho 10355569331642446be05292e3e1f8a51218827168cdclaireho switch ( sp->PosFormat ) 10365569331642446be05292e3e1f8a51218827168cdclaireho { 10375569331642446be05292e3e1f8a51218827168cdclaireho case 1: 10385569331642446be05292e3e1f8a51218827168cdclaireho error = Get_ValueRecord( gpi, &sp->spf.spf1.Value, 10395569331642446be05292e3e1f8a51218827168cdclaireho sp->ValueFormat, POSITION( buffer->in_pos ) ); 10405569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 10415569331642446be05292e3e1f8a51218827168cdclaireho return error; 10425569331642446be05292e3e1f8a51218827168cdclaireho break; 10435569331642446be05292e3e1f8a51218827168cdclaireho 10445569331642446be05292e3e1f8a51218827168cdclaireho case 2: 10455569331642446be05292e3e1f8a51218827168cdclaireho if ( index >= sp->spf.spf2.ValueCount ) 10465569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable); 10475569331642446be05292e3e1f8a51218827168cdclaireho error = Get_ValueRecord( gpi, &sp->spf.spf2.Value[index], 10485569331642446be05292e3e1f8a51218827168cdclaireho sp->ValueFormat, POSITION( buffer->in_pos ) ); 10495569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 10505569331642446be05292e3e1f8a51218827168cdclaireho return error; 10515569331642446be05292e3e1f8a51218827168cdclaireho break; 10525569331642446be05292e3e1f8a51218827168cdclaireho 10535569331642446be05292e3e1f8a51218827168cdclaireho default: 10545569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable); 10555569331642446be05292e3e1f8a51218827168cdclaireho } 10565569331642446be05292e3e1f8a51218827168cdclaireho 10575569331642446be05292e3e1f8a51218827168cdclaireho (buffer->in_pos)++; 10585569331642446be05292e3e1f8a51218827168cdclaireho 10595569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 10605569331642446be05292e3e1f8a51218827168cdclaireho} 10615569331642446be05292e3e1f8a51218827168cdclaireho 10625569331642446be05292e3e1f8a51218827168cdclaireho 10635569331642446be05292e3e1f8a51218827168cdclaireho/* LookupType 2 */ 10645569331642446be05292e3e1f8a51218827168cdclaireho 10655569331642446be05292e3e1f8a51218827168cdclaireho/* PairSet */ 10665569331642446be05292e3e1f8a51218827168cdclaireho 10675569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_PairSet ( HB_PairSet* ps, 10685569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort format1, 10695569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort format2, 10705569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 10715569331642446be05292e3e1f8a51218827168cdclaireho{ 10725569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 10735569331642446be05292e3e1f8a51218827168cdclaireho 10745569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, m, count; 10755569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt base_offset; 10765569331642446be05292e3e1f8a51218827168cdclaireho 10775569331642446be05292e3e1f8a51218827168cdclaireho HB_PairValueRecord* pvr; 10785569331642446be05292e3e1f8a51218827168cdclaireho 10795569331642446be05292e3e1f8a51218827168cdclaireho 10805569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 10815569331642446be05292e3e1f8a51218827168cdclaireho 10825569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 10835569331642446be05292e3e1f8a51218827168cdclaireho return error; 10845569331642446be05292e3e1f8a51218827168cdclaireho 10855569331642446be05292e3e1f8a51218827168cdclaireho count = ps->PairValueCount = GET_UShort(); 10865569331642446be05292e3e1f8a51218827168cdclaireho 10875569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 10885569331642446be05292e3e1f8a51218827168cdclaireho 10895569331642446be05292e3e1f8a51218827168cdclaireho ps->PairValueRecord = NULL; 10905569331642446be05292e3e1f8a51218827168cdclaireho 10915569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( ps->PairValueRecord, count, HB_PairValueRecord ) ) 10925569331642446be05292e3e1f8a51218827168cdclaireho return error; 10935569331642446be05292e3e1f8a51218827168cdclaireho 10945569331642446be05292e3e1f8a51218827168cdclaireho pvr = ps->PairValueRecord; 10955569331642446be05292e3e1f8a51218827168cdclaireho 10965569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 10975569331642446be05292e3e1f8a51218827168cdclaireho { 10985569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 10995569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 11005569331642446be05292e3e1f8a51218827168cdclaireho 11015569331642446be05292e3e1f8a51218827168cdclaireho pvr[n].SecondGlyph = GET_UShort(); 11025569331642446be05292e3e1f8a51218827168cdclaireho 11035569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 11045569331642446be05292e3e1f8a51218827168cdclaireho 11055569331642446be05292e3e1f8a51218827168cdclaireho if ( format1 ) 11065569331642446be05292e3e1f8a51218827168cdclaireho { 11075569331642446be05292e3e1f8a51218827168cdclaireho error = Load_ValueRecord( &pvr[n].Value1, format1, 11085569331642446be05292e3e1f8a51218827168cdclaireho base_offset, stream ); 11095569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 11105569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 11115569331642446be05292e3e1f8a51218827168cdclaireho } 11125569331642446be05292e3e1f8a51218827168cdclaireho if ( format2 ) 11135569331642446be05292e3e1f8a51218827168cdclaireho { 11145569331642446be05292e3e1f8a51218827168cdclaireho error = Load_ValueRecord( &pvr[n].Value2, format2, 11155569331642446be05292e3e1f8a51218827168cdclaireho base_offset, stream ); 11165569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 11175569331642446be05292e3e1f8a51218827168cdclaireho { 11185569331642446be05292e3e1f8a51218827168cdclaireho if ( format1 ) 11195569331642446be05292e3e1f8a51218827168cdclaireho Free_ValueRecord( &pvr[n].Value1, format1 ); 11205569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 11215569331642446be05292e3e1f8a51218827168cdclaireho } 11225569331642446be05292e3e1f8a51218827168cdclaireho } 11235569331642446be05292e3e1f8a51218827168cdclaireho } 11245569331642446be05292e3e1f8a51218827168cdclaireho 11255569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 11265569331642446be05292e3e1f8a51218827168cdclaireho 11275569331642446be05292e3e1f8a51218827168cdclairehoFail: 11285569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; m++ ) 11295569331642446be05292e3e1f8a51218827168cdclaireho { 11305569331642446be05292e3e1f8a51218827168cdclaireho if ( format1 ) 11315569331642446be05292e3e1f8a51218827168cdclaireho Free_ValueRecord( &pvr[m].Value1, format1 ); 11325569331642446be05292e3e1f8a51218827168cdclaireho if ( format2 ) 11335569331642446be05292e3e1f8a51218827168cdclaireho Free_ValueRecord( &pvr[m].Value2, format2 ); 11345569331642446be05292e3e1f8a51218827168cdclaireho } 11355569331642446be05292e3e1f8a51218827168cdclaireho 11365569331642446be05292e3e1f8a51218827168cdclaireho FREE( pvr ); 11375569331642446be05292e3e1f8a51218827168cdclaireho return error; 11385569331642446be05292e3e1f8a51218827168cdclaireho} 11395569331642446be05292e3e1f8a51218827168cdclaireho 11405569331642446be05292e3e1f8a51218827168cdclaireho 11415569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_PairSet( HB_PairSet* ps, 11425569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort format1, 11435569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort format2 ) 11445569331642446be05292e3e1f8a51218827168cdclaireho{ 11455569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 11465569331642446be05292e3e1f8a51218827168cdclaireho 11475569331642446be05292e3e1f8a51218827168cdclaireho HB_PairValueRecord* pvr; 11485569331642446be05292e3e1f8a51218827168cdclaireho 11495569331642446be05292e3e1f8a51218827168cdclaireho 11505569331642446be05292e3e1f8a51218827168cdclaireho if ( ps->PairValueRecord ) 11515569331642446be05292e3e1f8a51218827168cdclaireho { 11525569331642446be05292e3e1f8a51218827168cdclaireho count = ps->PairValueCount; 11535569331642446be05292e3e1f8a51218827168cdclaireho pvr = ps->PairValueRecord; 11545569331642446be05292e3e1f8a51218827168cdclaireho 11555569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 11565569331642446be05292e3e1f8a51218827168cdclaireho { 11575569331642446be05292e3e1f8a51218827168cdclaireho if ( format1 ) 11585569331642446be05292e3e1f8a51218827168cdclaireho Free_ValueRecord( &pvr[n].Value1, format1 ); 11595569331642446be05292e3e1f8a51218827168cdclaireho if ( format2 ) 11605569331642446be05292e3e1f8a51218827168cdclaireho Free_ValueRecord( &pvr[n].Value2, format2 ); 11615569331642446be05292e3e1f8a51218827168cdclaireho } 11625569331642446be05292e3e1f8a51218827168cdclaireho 11635569331642446be05292e3e1f8a51218827168cdclaireho FREE( pvr ); 11645569331642446be05292e3e1f8a51218827168cdclaireho } 11655569331642446be05292e3e1f8a51218827168cdclaireho} 11665569331642446be05292e3e1f8a51218827168cdclaireho 11675569331642446be05292e3e1f8a51218827168cdclaireho 11685569331642446be05292e3e1f8a51218827168cdclaireho/* PairPosFormat1 */ 11695569331642446be05292e3e1f8a51218827168cdclaireho 11705569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_PairPos1( HB_PairPosFormat1* ppf1, 11715569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort format1, 11725569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort format2, 11735569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 11745569331642446be05292e3e1f8a51218827168cdclaireho{ 11755569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 11765569331642446be05292e3e1f8a51218827168cdclaireho 11775569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, m, count; 11785569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 11795569331642446be05292e3e1f8a51218827168cdclaireho 11805569331642446be05292e3e1f8a51218827168cdclaireho HB_PairSet* ps; 11815569331642446be05292e3e1f8a51218827168cdclaireho 11825569331642446be05292e3e1f8a51218827168cdclaireho 11835569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos() - 8L; 11845569331642446be05292e3e1f8a51218827168cdclaireho 11855569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 11865569331642446be05292e3e1f8a51218827168cdclaireho return error; 11875569331642446be05292e3e1f8a51218827168cdclaireho 11885569331642446be05292e3e1f8a51218827168cdclaireho count = ppf1->PairSetCount = GET_UShort(); 11895569331642446be05292e3e1f8a51218827168cdclaireho 11905569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 11915569331642446be05292e3e1f8a51218827168cdclaireho 11925569331642446be05292e3e1f8a51218827168cdclaireho ppf1->PairSet = NULL; 11935569331642446be05292e3e1f8a51218827168cdclaireho 11945569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( ppf1->PairSet, count, HB_PairSet ) ) 11955569331642446be05292e3e1f8a51218827168cdclaireho return error; 11965569331642446be05292e3e1f8a51218827168cdclaireho 11975569331642446be05292e3e1f8a51218827168cdclaireho ps = ppf1->PairSet; 11985569331642446be05292e3e1f8a51218827168cdclaireho 11995569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 12005569331642446be05292e3e1f8a51218827168cdclaireho { 12015569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 12025569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 12035569331642446be05292e3e1f8a51218827168cdclaireho 12045569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 12055569331642446be05292e3e1f8a51218827168cdclaireho 12065569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 12075569331642446be05292e3e1f8a51218827168cdclaireho 12085569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 12095569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 12105569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_PairSet( &ps[n], format1, 12115569331642446be05292e3e1f8a51218827168cdclaireho format2, stream ) ) != HB_Err_Ok ) 12125569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 12135569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 12145569331642446be05292e3e1f8a51218827168cdclaireho } 12155569331642446be05292e3e1f8a51218827168cdclaireho 12165569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 12175569331642446be05292e3e1f8a51218827168cdclaireho 12185569331642446be05292e3e1f8a51218827168cdclairehoFail: 12195569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; m++ ) 12205569331642446be05292e3e1f8a51218827168cdclaireho Free_PairSet( &ps[m], format1, format2 ); 12215569331642446be05292e3e1f8a51218827168cdclaireho 12225569331642446be05292e3e1f8a51218827168cdclaireho FREE( ps ); 12235569331642446be05292e3e1f8a51218827168cdclaireho return error; 12245569331642446be05292e3e1f8a51218827168cdclaireho} 12255569331642446be05292e3e1f8a51218827168cdclaireho 12265569331642446be05292e3e1f8a51218827168cdclaireho 12275569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_PairPos1( HB_PairPosFormat1* ppf1, 12285569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort format1, 12295569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort format2 ) 12305569331642446be05292e3e1f8a51218827168cdclaireho{ 12315569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 12325569331642446be05292e3e1f8a51218827168cdclaireho 12335569331642446be05292e3e1f8a51218827168cdclaireho HB_PairSet* ps; 12345569331642446be05292e3e1f8a51218827168cdclaireho 12355569331642446be05292e3e1f8a51218827168cdclaireho 12365569331642446be05292e3e1f8a51218827168cdclaireho if ( ppf1->PairSet ) 12375569331642446be05292e3e1f8a51218827168cdclaireho { 12385569331642446be05292e3e1f8a51218827168cdclaireho count = ppf1->PairSetCount; 12395569331642446be05292e3e1f8a51218827168cdclaireho ps = ppf1->PairSet; 12405569331642446be05292e3e1f8a51218827168cdclaireho 12415569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 12425569331642446be05292e3e1f8a51218827168cdclaireho Free_PairSet( &ps[n], format1, format2 ); 12435569331642446be05292e3e1f8a51218827168cdclaireho 12445569331642446be05292e3e1f8a51218827168cdclaireho FREE( ps ); 12455569331642446be05292e3e1f8a51218827168cdclaireho } 12465569331642446be05292e3e1f8a51218827168cdclaireho} 12475569331642446be05292e3e1f8a51218827168cdclaireho 12485569331642446be05292e3e1f8a51218827168cdclaireho 12495569331642446be05292e3e1f8a51218827168cdclaireho/* PairPosFormat2 */ 12505569331642446be05292e3e1f8a51218827168cdclaireho 12515569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_PairPos2( HB_PairPosFormat2* ppf2, 12525569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort format1, 12535569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort format2, 12545569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 12555569331642446be05292e3e1f8a51218827168cdclaireho{ 12565569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 12575569331642446be05292e3e1f8a51218827168cdclaireho 12585569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort m, n, k, count1, count2; 12595569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset1, new_offset2, base_offset; 12605569331642446be05292e3e1f8a51218827168cdclaireho 12615569331642446be05292e3e1f8a51218827168cdclaireho HB_Class1Record* c1r; 12625569331642446be05292e3e1f8a51218827168cdclaireho HB_Class2Record* c2r; 12635569331642446be05292e3e1f8a51218827168cdclaireho 12645569331642446be05292e3e1f8a51218827168cdclaireho 12655569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos() - 8L; 12665569331642446be05292e3e1f8a51218827168cdclaireho 12675569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 8L ) ) 12685569331642446be05292e3e1f8a51218827168cdclaireho return error; 12695569331642446be05292e3e1f8a51218827168cdclaireho 12705569331642446be05292e3e1f8a51218827168cdclaireho new_offset1 = GET_UShort() + base_offset; 12715569331642446be05292e3e1f8a51218827168cdclaireho new_offset2 = GET_UShort() + base_offset; 12725569331642446be05292e3e1f8a51218827168cdclaireho 12735569331642446be05292e3e1f8a51218827168cdclaireho /* `Class1Count' and `Class2Count' are the upper limits for class 12745569331642446be05292e3e1f8a51218827168cdclaireho values, thus we read it now to make additional safety checks. */ 12755569331642446be05292e3e1f8a51218827168cdclaireho 12765569331642446be05292e3e1f8a51218827168cdclaireho count1 = ppf2->Class1Count = GET_UShort(); 12775569331642446be05292e3e1f8a51218827168cdclaireho count2 = ppf2->Class2Count = GET_UShort(); 12785569331642446be05292e3e1f8a51218827168cdclaireho 12795569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 12805569331642446be05292e3e1f8a51218827168cdclaireho 12815569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 12825569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset1 ) || 12835569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_ClassDefinition( &ppf2->ClassDef1, count1, 12845569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 12855569331642446be05292e3e1f8a51218827168cdclaireho return error; 12865569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset2 ) || 12875569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_ClassDefinition( &ppf2->ClassDef2, count2, 12885569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 12895569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 12905569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 12915569331642446be05292e3e1f8a51218827168cdclaireho 12925569331642446be05292e3e1f8a51218827168cdclaireho ppf2->Class1Record = NULL; 12935569331642446be05292e3e1f8a51218827168cdclaireho 12945569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( ppf2->Class1Record, count1, HB_Class1Record ) ) 12955569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 12965569331642446be05292e3e1f8a51218827168cdclaireho 12975569331642446be05292e3e1f8a51218827168cdclaireho c1r = ppf2->Class1Record; 12985569331642446be05292e3e1f8a51218827168cdclaireho 12995569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < count1; m++ ) 13005569331642446be05292e3e1f8a51218827168cdclaireho { 13015569331642446be05292e3e1f8a51218827168cdclaireho c1r[m].Class2Record = NULL; 13025569331642446be05292e3e1f8a51218827168cdclaireho 13035569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( c1r[m].Class2Record, count2, HB_Class2Record ) ) 13045569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 13055569331642446be05292e3e1f8a51218827168cdclaireho 13065569331642446be05292e3e1f8a51218827168cdclaireho c2r = c1r[m].Class2Record; 13075569331642446be05292e3e1f8a51218827168cdclaireho 13085569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count2; n++ ) 13095569331642446be05292e3e1f8a51218827168cdclaireho { 13105569331642446be05292e3e1f8a51218827168cdclaireho if ( format1 ) 13115569331642446be05292e3e1f8a51218827168cdclaireho { 13125569331642446be05292e3e1f8a51218827168cdclaireho error = Load_ValueRecord( &c2r[n].Value1, format1, 13135569331642446be05292e3e1f8a51218827168cdclaireho base_offset, stream ); 13145569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 13155569331642446be05292e3e1f8a51218827168cdclaireho goto Fail0; 13165569331642446be05292e3e1f8a51218827168cdclaireho } 13175569331642446be05292e3e1f8a51218827168cdclaireho if ( format2 ) 13185569331642446be05292e3e1f8a51218827168cdclaireho { 13195569331642446be05292e3e1f8a51218827168cdclaireho error = Load_ValueRecord( &c2r[n].Value2, format2, 13205569331642446be05292e3e1f8a51218827168cdclaireho base_offset, stream ); 13215569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 13225569331642446be05292e3e1f8a51218827168cdclaireho { 13235569331642446be05292e3e1f8a51218827168cdclaireho if ( format1 ) 13245569331642446be05292e3e1f8a51218827168cdclaireho Free_ValueRecord( &c2r[n].Value1, format1 ); 13255569331642446be05292e3e1f8a51218827168cdclaireho goto Fail0; 13265569331642446be05292e3e1f8a51218827168cdclaireho } 13275569331642446be05292e3e1f8a51218827168cdclaireho } 13285569331642446be05292e3e1f8a51218827168cdclaireho } 13295569331642446be05292e3e1f8a51218827168cdclaireho 13305569331642446be05292e3e1f8a51218827168cdclaireho continue; 13315569331642446be05292e3e1f8a51218827168cdclaireho 13325569331642446be05292e3e1f8a51218827168cdclaireho Fail0: 13335569331642446be05292e3e1f8a51218827168cdclaireho for ( k = 0; k < n; k++ ) 13345569331642446be05292e3e1f8a51218827168cdclaireho { 13355569331642446be05292e3e1f8a51218827168cdclaireho if ( format1 ) 13365569331642446be05292e3e1f8a51218827168cdclaireho Free_ValueRecord( &c2r[k].Value1, format1 ); 13375569331642446be05292e3e1f8a51218827168cdclaireho if ( format2 ) 13385569331642446be05292e3e1f8a51218827168cdclaireho Free_ValueRecord( &c2r[k].Value2, format2 ); 13395569331642446be05292e3e1f8a51218827168cdclaireho } 13405569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 13415569331642446be05292e3e1f8a51218827168cdclaireho } 13425569331642446be05292e3e1f8a51218827168cdclaireho 13435569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 13445569331642446be05292e3e1f8a51218827168cdclaireho 13455569331642446be05292e3e1f8a51218827168cdclairehoFail1: 13465569331642446be05292e3e1f8a51218827168cdclaireho for ( k = 0; k < m; k++ ) 13475569331642446be05292e3e1f8a51218827168cdclaireho { 13485569331642446be05292e3e1f8a51218827168cdclaireho c2r = c1r[k].Class2Record; 13495569331642446be05292e3e1f8a51218827168cdclaireho 13505569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count2; n++ ) 13515569331642446be05292e3e1f8a51218827168cdclaireho { 13525569331642446be05292e3e1f8a51218827168cdclaireho if ( format1 ) 13535569331642446be05292e3e1f8a51218827168cdclaireho Free_ValueRecord( &c2r[n].Value1, format1 ); 13545569331642446be05292e3e1f8a51218827168cdclaireho if ( format2 ) 13555569331642446be05292e3e1f8a51218827168cdclaireho Free_ValueRecord( &c2r[n].Value2, format2 ); 13565569331642446be05292e3e1f8a51218827168cdclaireho } 13575569331642446be05292e3e1f8a51218827168cdclaireho 13585569331642446be05292e3e1f8a51218827168cdclaireho FREE( c2r ); 13595569331642446be05292e3e1f8a51218827168cdclaireho } 13605569331642446be05292e3e1f8a51218827168cdclaireho 13615569331642446be05292e3e1f8a51218827168cdclaireho FREE( c1r ); 13625569331642446be05292e3e1f8a51218827168cdclairehoFail2: 13635569331642446be05292e3e1f8a51218827168cdclaireho 13645569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_ClassDefinition( &ppf2->ClassDef2 ); 13655569331642446be05292e3e1f8a51218827168cdclaireho 13665569331642446be05292e3e1f8a51218827168cdclairehoFail3: 13675569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_ClassDefinition( &ppf2->ClassDef1 ); 13685569331642446be05292e3e1f8a51218827168cdclaireho return error; 13695569331642446be05292e3e1f8a51218827168cdclaireho} 13705569331642446be05292e3e1f8a51218827168cdclaireho 13715569331642446be05292e3e1f8a51218827168cdclaireho 13725569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_PairPos2( HB_PairPosFormat2* ppf2, 13735569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort format1, 13745569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort format2) 13755569331642446be05292e3e1f8a51218827168cdclaireho{ 13765569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort m, n, count1, count2; 13775569331642446be05292e3e1f8a51218827168cdclaireho 13785569331642446be05292e3e1f8a51218827168cdclaireho HB_Class1Record* c1r; 13795569331642446be05292e3e1f8a51218827168cdclaireho HB_Class2Record* c2r; 13805569331642446be05292e3e1f8a51218827168cdclaireho 13815569331642446be05292e3e1f8a51218827168cdclaireho 13825569331642446be05292e3e1f8a51218827168cdclaireho if ( ppf2->Class1Record ) 13835569331642446be05292e3e1f8a51218827168cdclaireho { 13845569331642446be05292e3e1f8a51218827168cdclaireho c1r = ppf2->Class1Record; 13855569331642446be05292e3e1f8a51218827168cdclaireho count1 = ppf2->Class1Count; 13865569331642446be05292e3e1f8a51218827168cdclaireho count2 = ppf2->Class2Count; 13875569331642446be05292e3e1f8a51218827168cdclaireho 13885569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < count1; m++ ) 13895569331642446be05292e3e1f8a51218827168cdclaireho { 13905569331642446be05292e3e1f8a51218827168cdclaireho c2r = c1r[m].Class2Record; 13915569331642446be05292e3e1f8a51218827168cdclaireho 13925569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count2; n++ ) 13935569331642446be05292e3e1f8a51218827168cdclaireho { 13945569331642446be05292e3e1f8a51218827168cdclaireho if ( format1 ) 13955569331642446be05292e3e1f8a51218827168cdclaireho Free_ValueRecord( &c2r[n].Value1, format1 ); 13965569331642446be05292e3e1f8a51218827168cdclaireho if ( format2 ) 13975569331642446be05292e3e1f8a51218827168cdclaireho Free_ValueRecord( &c2r[n].Value2, format2 ); 13985569331642446be05292e3e1f8a51218827168cdclaireho } 13995569331642446be05292e3e1f8a51218827168cdclaireho 14005569331642446be05292e3e1f8a51218827168cdclaireho FREE( c2r ); 14015569331642446be05292e3e1f8a51218827168cdclaireho } 14025569331642446be05292e3e1f8a51218827168cdclaireho 14035569331642446be05292e3e1f8a51218827168cdclaireho FREE( c1r ); 14045569331642446be05292e3e1f8a51218827168cdclaireho 14055569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_ClassDefinition( &ppf2->ClassDef2 ); 14065569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_ClassDefinition( &ppf2->ClassDef1 ); 14075569331642446be05292e3e1f8a51218827168cdclaireho } 14085569331642446be05292e3e1f8a51218827168cdclaireho} 14095569331642446be05292e3e1f8a51218827168cdclaireho 14105569331642446be05292e3e1f8a51218827168cdclaireho 14115569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_PairPos( HB_GPOS_SubTable* st, 14125569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 14135569331642446be05292e3e1f8a51218827168cdclaireho{ 14145569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 14155569331642446be05292e3e1f8a51218827168cdclaireho HB_PairPos* pp = &st->pair; 14165569331642446be05292e3e1f8a51218827168cdclaireho 14175569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort format1, format2; 14185569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 14195569331642446be05292e3e1f8a51218827168cdclaireho 14205569331642446be05292e3e1f8a51218827168cdclaireho 14215569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 14225569331642446be05292e3e1f8a51218827168cdclaireho 14235569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 8L ) ) 14245569331642446be05292e3e1f8a51218827168cdclaireho return error; 14255569331642446be05292e3e1f8a51218827168cdclaireho 14265569331642446be05292e3e1f8a51218827168cdclaireho pp->PosFormat = GET_UShort(); 14275569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 14285569331642446be05292e3e1f8a51218827168cdclaireho 14295569331642446be05292e3e1f8a51218827168cdclaireho format1 = pp->ValueFormat1 = GET_UShort(); 14305569331642446be05292e3e1f8a51218827168cdclaireho format2 = pp->ValueFormat2 = GET_UShort(); 14315569331642446be05292e3e1f8a51218827168cdclaireho 14325569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 14335569331642446be05292e3e1f8a51218827168cdclaireho 14345569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 14355569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 14365569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &pp->Coverage, stream ) ) != HB_Err_Ok ) 14375569331642446be05292e3e1f8a51218827168cdclaireho return error; 14385569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 14395569331642446be05292e3e1f8a51218827168cdclaireho 14405569331642446be05292e3e1f8a51218827168cdclaireho switch ( pp->PosFormat ) 14415569331642446be05292e3e1f8a51218827168cdclaireho { 14425569331642446be05292e3e1f8a51218827168cdclaireho case 1: 14435569331642446be05292e3e1f8a51218827168cdclaireho error = Load_PairPos1( &pp->ppf.ppf1, format1, format2, stream ); 14445569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 14455569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 14465569331642446be05292e3e1f8a51218827168cdclaireho break; 14475569331642446be05292e3e1f8a51218827168cdclaireho 14485569331642446be05292e3e1f8a51218827168cdclaireho case 2: 14495569331642446be05292e3e1f8a51218827168cdclaireho error = Load_PairPos2( &pp->ppf.ppf2, format1, format2, stream ); 14505569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 14515569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 14525569331642446be05292e3e1f8a51218827168cdclaireho break; 14535569331642446be05292e3e1f8a51218827168cdclaireho 14545569331642446be05292e3e1f8a51218827168cdclaireho default: 14555569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable_Format); 14565569331642446be05292e3e1f8a51218827168cdclaireho } 14575569331642446be05292e3e1f8a51218827168cdclaireho 14585569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 14595569331642446be05292e3e1f8a51218827168cdclaireho 14605569331642446be05292e3e1f8a51218827168cdclairehoFail: 14615569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &pp->Coverage ); 14625569331642446be05292e3e1f8a51218827168cdclaireho return error; 14635569331642446be05292e3e1f8a51218827168cdclaireho} 14645569331642446be05292e3e1f8a51218827168cdclaireho 14655569331642446be05292e3e1f8a51218827168cdclaireho 14665569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_PairPos( HB_GPOS_SubTable* st ) 14675569331642446be05292e3e1f8a51218827168cdclaireho{ 14685569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort format1, format2; 14695569331642446be05292e3e1f8a51218827168cdclaireho HB_PairPos* pp = &st->pair; 14705569331642446be05292e3e1f8a51218827168cdclaireho 14715569331642446be05292e3e1f8a51218827168cdclaireho 14725569331642446be05292e3e1f8a51218827168cdclaireho format1 = pp->ValueFormat1; 14735569331642446be05292e3e1f8a51218827168cdclaireho format2 = pp->ValueFormat2; 14745569331642446be05292e3e1f8a51218827168cdclaireho 14755569331642446be05292e3e1f8a51218827168cdclaireho switch ( pp->PosFormat ) 14765569331642446be05292e3e1f8a51218827168cdclaireho { 14775569331642446be05292e3e1f8a51218827168cdclaireho case 1: 14785569331642446be05292e3e1f8a51218827168cdclaireho Free_PairPos1( &pp->ppf.ppf1, format1, format2 ); 14795569331642446be05292e3e1f8a51218827168cdclaireho break; 14805569331642446be05292e3e1f8a51218827168cdclaireho 14815569331642446be05292e3e1f8a51218827168cdclaireho case 2: 14825569331642446be05292e3e1f8a51218827168cdclaireho Free_PairPos2( &pp->ppf.ppf2, format1, format2 ); 14835569331642446be05292e3e1f8a51218827168cdclaireho break; 14845569331642446be05292e3e1f8a51218827168cdclaireho 14855569331642446be05292e3e1f8a51218827168cdclaireho default: 14865569331642446be05292e3e1f8a51218827168cdclaireho break; 14875569331642446be05292e3e1f8a51218827168cdclaireho } 14885569331642446be05292e3e1f8a51218827168cdclaireho 14895569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &pp->Coverage ); 14905569331642446be05292e3e1f8a51218827168cdclaireho} 14915569331642446be05292e3e1f8a51218827168cdclaireho 14925569331642446be05292e3e1f8a51218827168cdclaireho 14935569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Lookup_PairPos1( GPOS_Instance* gpi, 14945569331642446be05292e3e1f8a51218827168cdclaireho HB_PairPosFormat1* ppf1, 14955569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 14965569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt first_pos, 14975569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort index, 14985569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort format1, 14995569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort format2 ) 15005569331642446be05292e3e1f8a51218827168cdclaireho{ 15015569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 15025569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort numpvr, glyph2; 15035569331642446be05292e3e1f8a51218827168cdclaireho 15045569331642446be05292e3e1f8a51218827168cdclaireho HB_PairValueRecord* pvr; 15055569331642446be05292e3e1f8a51218827168cdclaireho 15065569331642446be05292e3e1f8a51218827168cdclaireho 15075569331642446be05292e3e1f8a51218827168cdclaireho if ( index >= ppf1->PairSetCount ) 15085569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable); 15095569331642446be05292e3e1f8a51218827168cdclaireho 15105569331642446be05292e3e1f8a51218827168cdclaireho pvr = ppf1->PairSet[index].PairValueRecord; 15115569331642446be05292e3e1f8a51218827168cdclaireho if ( !pvr ) 15125569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable); 15135569331642446be05292e3e1f8a51218827168cdclaireho 15145569331642446be05292e3e1f8a51218827168cdclaireho glyph2 = IN_CURGLYPH(); 15155569331642446be05292e3e1f8a51218827168cdclaireho 15165569331642446be05292e3e1f8a51218827168cdclaireho for ( numpvr = ppf1->PairSet[index].PairValueCount; 15175569331642446be05292e3e1f8a51218827168cdclaireho numpvr; 15185569331642446be05292e3e1f8a51218827168cdclaireho numpvr--, pvr++ ) 15195569331642446be05292e3e1f8a51218827168cdclaireho { 15205569331642446be05292e3e1f8a51218827168cdclaireho if ( glyph2 == pvr->SecondGlyph ) 15215569331642446be05292e3e1f8a51218827168cdclaireho { 15225569331642446be05292e3e1f8a51218827168cdclaireho error = Get_ValueRecord( gpi, &pvr->Value1, format1, 15235569331642446be05292e3e1f8a51218827168cdclaireho POSITION( first_pos ) ); 15245569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 15255569331642446be05292e3e1f8a51218827168cdclaireho return error; 15265569331642446be05292e3e1f8a51218827168cdclaireho return Get_ValueRecord( gpi, &pvr->Value2, format2, 15275569331642446be05292e3e1f8a51218827168cdclaireho POSITION( buffer->in_pos ) ); 15285569331642446be05292e3e1f8a51218827168cdclaireho } 15295569331642446be05292e3e1f8a51218827168cdclaireho } 15305569331642446be05292e3e1f8a51218827168cdclaireho 15315569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 15325569331642446be05292e3e1f8a51218827168cdclaireho} 15335569331642446be05292e3e1f8a51218827168cdclaireho 15345569331642446be05292e3e1f8a51218827168cdclaireho 15355569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Lookup_PairPos2( GPOS_Instance* gpi, 15365569331642446be05292e3e1f8a51218827168cdclaireho HB_PairPosFormat2* ppf2, 15375569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 15385569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt first_pos, 15395569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort format1, 15405569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort format2 ) 15415569331642446be05292e3e1f8a51218827168cdclaireho{ 15425569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 15435569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort cl1 = 0, cl2 = 0; /* shut compiler up */ 15445569331642446be05292e3e1f8a51218827168cdclaireho 15455569331642446be05292e3e1f8a51218827168cdclaireho HB_Class1Record* c1r; 15465569331642446be05292e3e1f8a51218827168cdclaireho HB_Class2Record* c2r; 15475569331642446be05292e3e1f8a51218827168cdclaireho 15485569331642446be05292e3e1f8a51218827168cdclaireho 15495569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Get_Class( &ppf2->ClassDef1, IN_GLYPH( first_pos ), 15505569331642446be05292e3e1f8a51218827168cdclaireho &cl1, NULL ); 15515569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 15525569331642446be05292e3e1f8a51218827168cdclaireho return error; 15535569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Get_Class( &ppf2->ClassDef2, IN_CURGLYPH(), 15545569331642446be05292e3e1f8a51218827168cdclaireho &cl2, NULL ); 15555569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 15565569331642446be05292e3e1f8a51218827168cdclaireho return error; 15575569331642446be05292e3e1f8a51218827168cdclaireho 15585569331642446be05292e3e1f8a51218827168cdclaireho c1r = &ppf2->Class1Record[cl1]; 15595569331642446be05292e3e1f8a51218827168cdclaireho if ( !c1r ) 15605569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable); 15615569331642446be05292e3e1f8a51218827168cdclaireho c2r = &c1r->Class2Record[cl2]; 15625569331642446be05292e3e1f8a51218827168cdclaireho 15635569331642446be05292e3e1f8a51218827168cdclaireho error = Get_ValueRecord( gpi, &c2r->Value1, format1, POSITION( first_pos ) ); 15645569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 15655569331642446be05292e3e1f8a51218827168cdclaireho return error; 15665569331642446be05292e3e1f8a51218827168cdclaireho return Get_ValueRecord( gpi, &c2r->Value2, format2, POSITION( buffer->in_pos ) ); 15675569331642446be05292e3e1f8a51218827168cdclaireho} 15685569331642446be05292e3e1f8a51218827168cdclaireho 15695569331642446be05292e3e1f8a51218827168cdclaireho 15705569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Lookup_PairPos( GPOS_Instance* gpi, 15715569331642446be05292e3e1f8a51218827168cdclaireho HB_GPOS_SubTable* st, 15725569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 15735569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort flags, 15745569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 15755569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 15765569331642446be05292e3e1f8a51218827168cdclaireho{ 15775569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 15785569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort index, property; 15795569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt first_pos; 15805569331642446be05292e3e1f8a51218827168cdclaireho HB_GPOSHeader* gpos = gpi->gpos; 15815569331642446be05292e3e1f8a51218827168cdclaireho HB_PairPos* pp = &st->pair; 15825569331642446be05292e3e1f8a51218827168cdclaireho 15835569331642446be05292e3e1f8a51218827168cdclaireho HB_UNUSED(nesting_level); 15845569331642446be05292e3e1f8a51218827168cdclaireho 15855569331642446be05292e3e1f8a51218827168cdclaireho if ( buffer->in_pos >= buffer->in_length - 1 ) 15865569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; /* Not enough glyphs in stream */ 15875569331642446be05292e3e1f8a51218827168cdclaireho 15885569331642446be05292e3e1f8a51218827168cdclaireho if ( context_length != 0xFFFF && context_length < 2 ) 15895569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 15905569331642446be05292e3e1f8a51218827168cdclaireho 15915569331642446be05292e3e1f8a51218827168cdclaireho if ( CHECK_Property( gpos->gdef, IN_CURITEM(), flags, &property ) ) 15925569331642446be05292e3e1f8a51218827168cdclaireho return error; 15935569331642446be05292e3e1f8a51218827168cdclaireho 15945569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &pp->Coverage, IN_CURGLYPH(), &index ); 15955569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 15965569331642446be05292e3e1f8a51218827168cdclaireho return error; 15975569331642446be05292e3e1f8a51218827168cdclaireho 15985569331642446be05292e3e1f8a51218827168cdclaireho /* second glyph */ 15995569331642446be05292e3e1f8a51218827168cdclaireho 16005569331642446be05292e3e1f8a51218827168cdclaireho first_pos = buffer->in_pos; 16015569331642446be05292e3e1f8a51218827168cdclaireho (buffer->in_pos)++; 16025569331642446be05292e3e1f8a51218827168cdclaireho 16035569331642446be05292e3e1f8a51218827168cdclaireho while ( CHECK_Property( gpos->gdef, IN_CURITEM(), 16045569331642446be05292e3e1f8a51218827168cdclaireho flags, &property ) ) 16055569331642446be05292e3e1f8a51218827168cdclaireho { 16065569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 16075569331642446be05292e3e1f8a51218827168cdclaireho return error; 16085569331642446be05292e3e1f8a51218827168cdclaireho 16095569331642446be05292e3e1f8a51218827168cdclaireho if ( buffer->in_pos == buffer->in_length ) 16105569331642446be05292e3e1f8a51218827168cdclaireho { 16115569331642446be05292e3e1f8a51218827168cdclaireho buffer->in_pos = first_pos; 16125569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 16135569331642446be05292e3e1f8a51218827168cdclaireho } 16145569331642446be05292e3e1f8a51218827168cdclaireho (buffer->in_pos)++; 16155569331642446be05292e3e1f8a51218827168cdclaireho 16165569331642446be05292e3e1f8a51218827168cdclaireho } 16175569331642446be05292e3e1f8a51218827168cdclaireho 16185569331642446be05292e3e1f8a51218827168cdclaireho switch ( pp->PosFormat ) 16195569331642446be05292e3e1f8a51218827168cdclaireho { 16205569331642446be05292e3e1f8a51218827168cdclaireho case 1: 16215569331642446be05292e3e1f8a51218827168cdclaireho error = Lookup_PairPos1( gpi, &pp->ppf.ppf1, buffer, 16225569331642446be05292e3e1f8a51218827168cdclaireho first_pos, index, 16235569331642446be05292e3e1f8a51218827168cdclaireho pp->ValueFormat1, pp->ValueFormat2 ); 16245569331642446be05292e3e1f8a51218827168cdclaireho break; 16255569331642446be05292e3e1f8a51218827168cdclaireho 16265569331642446be05292e3e1f8a51218827168cdclaireho case 2: 16275569331642446be05292e3e1f8a51218827168cdclaireho error = Lookup_PairPos2( gpi, &pp->ppf.ppf2, buffer, first_pos, 16285569331642446be05292e3e1f8a51218827168cdclaireho pp->ValueFormat1, pp->ValueFormat2 ); 16295569331642446be05292e3e1f8a51218827168cdclaireho break; 16305569331642446be05292e3e1f8a51218827168cdclaireho 16315569331642446be05292e3e1f8a51218827168cdclaireho default: 16325569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable_Format); 16335569331642446be05292e3e1f8a51218827168cdclaireho } 16345569331642446be05292e3e1f8a51218827168cdclaireho 16355569331642446be05292e3e1f8a51218827168cdclaireho /* if we don't have coverage for the second glyph don't skip it for 16365569331642446be05292e3e1f8a51218827168cdclaireho further lookups but reset in_pos back to the first_glyph and let 16375569331642446be05292e3e1f8a51218827168cdclaireho the caller in Do_String_Lookup increment in_pos */ 16385569331642446be05292e3e1f8a51218827168cdclaireho if ( error == HB_Err_Not_Covered ) 16395569331642446be05292e3e1f8a51218827168cdclaireho buffer->in_pos = first_pos; 16405569331642446be05292e3e1f8a51218827168cdclaireho 16415569331642446be05292e3e1f8a51218827168cdclaireho /* adjusting the `next' glyph */ 16425569331642446be05292e3e1f8a51218827168cdclaireho 16435569331642446be05292e3e1f8a51218827168cdclaireho if ( pp->ValueFormat2 ) 16445569331642446be05292e3e1f8a51218827168cdclaireho (buffer->in_pos)++; 16455569331642446be05292e3e1f8a51218827168cdclaireho 16465569331642446be05292e3e1f8a51218827168cdclaireho return error; 16475569331642446be05292e3e1f8a51218827168cdclaireho} 16485569331642446be05292e3e1f8a51218827168cdclaireho 16495569331642446be05292e3e1f8a51218827168cdclaireho 16505569331642446be05292e3e1f8a51218827168cdclaireho/* LookupType 3 */ 16515569331642446be05292e3e1f8a51218827168cdclaireho 16525569331642446be05292e3e1f8a51218827168cdclaireho/* CursivePosFormat1 */ 16535569331642446be05292e3e1f8a51218827168cdclaireho 16545569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_CursivePos( HB_GPOS_SubTable* st, 16555569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 16565569331642446be05292e3e1f8a51218827168cdclaireho{ 16575569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 16585569331642446be05292e3e1f8a51218827168cdclaireho HB_CursivePos* cp = &st->cursive; 16595569331642446be05292e3e1f8a51218827168cdclaireho 16605569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, m, count; 16615569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 16625569331642446be05292e3e1f8a51218827168cdclaireho 16635569331642446be05292e3e1f8a51218827168cdclaireho HB_EntryExitRecord* eer; 16645569331642446be05292e3e1f8a51218827168cdclaireho 16655569331642446be05292e3e1f8a51218827168cdclaireho 16665569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 16675569331642446be05292e3e1f8a51218827168cdclaireho 16685569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 4L ) ) 16695569331642446be05292e3e1f8a51218827168cdclaireho return error; 16705569331642446be05292e3e1f8a51218827168cdclaireho 16715569331642446be05292e3e1f8a51218827168cdclaireho cp->PosFormat = GET_UShort(); 16725569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 16735569331642446be05292e3e1f8a51218827168cdclaireho 16745569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 16755569331642446be05292e3e1f8a51218827168cdclaireho 16765569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 16775569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 16785569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &cp->Coverage, stream ) ) != HB_Err_Ok ) 16795569331642446be05292e3e1f8a51218827168cdclaireho return error; 16805569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 16815569331642446be05292e3e1f8a51218827168cdclaireho 16825569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 16835569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 16845569331642446be05292e3e1f8a51218827168cdclaireho 16855569331642446be05292e3e1f8a51218827168cdclaireho count = cp->EntryExitCount = GET_UShort(); 16865569331642446be05292e3e1f8a51218827168cdclaireho 16875569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 16885569331642446be05292e3e1f8a51218827168cdclaireho 16895569331642446be05292e3e1f8a51218827168cdclaireho cp->EntryExitRecord = NULL; 16905569331642446be05292e3e1f8a51218827168cdclaireho 16915569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( cp->EntryExitRecord, count, HB_EntryExitRecord ) ) 16925569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 16935569331642446be05292e3e1f8a51218827168cdclaireho 16945569331642446be05292e3e1f8a51218827168cdclaireho eer = cp->EntryExitRecord; 16955569331642446be05292e3e1f8a51218827168cdclaireho 16965569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 16975569331642446be05292e3e1f8a51218827168cdclaireho { 16985569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt entry_offset; 16995569331642446be05292e3e1f8a51218827168cdclaireho 17005569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 17015569331642446be05292e3e1f8a51218827168cdclaireho return error; 17025569331642446be05292e3e1f8a51218827168cdclaireho 17035569331642446be05292e3e1f8a51218827168cdclaireho entry_offset = new_offset = GET_UShort(); 17045569331642446be05292e3e1f8a51218827168cdclaireho 17055569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 17065569331642446be05292e3e1f8a51218827168cdclaireho 17075569331642446be05292e3e1f8a51218827168cdclaireho if ( new_offset ) 17085569331642446be05292e3e1f8a51218827168cdclaireho { 17095569331642446be05292e3e1f8a51218827168cdclaireho new_offset += base_offset; 17105569331642446be05292e3e1f8a51218827168cdclaireho 17115569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 17125569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 17135569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_Anchor( &eer[n].EntryAnchor, 17145569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 17155569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 17165569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 17175569331642446be05292e3e1f8a51218827168cdclaireho } 17185569331642446be05292e3e1f8a51218827168cdclaireho else 17195569331642446be05292e3e1f8a51218827168cdclaireho eer[n].EntryAnchor.PosFormat = 0; 17205569331642446be05292e3e1f8a51218827168cdclaireho 17215569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 17225569331642446be05292e3e1f8a51218827168cdclaireho return error; 17235569331642446be05292e3e1f8a51218827168cdclaireho 17245569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort(); 17255569331642446be05292e3e1f8a51218827168cdclaireho 17265569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 17275569331642446be05292e3e1f8a51218827168cdclaireho 17285569331642446be05292e3e1f8a51218827168cdclaireho if ( new_offset ) 17295569331642446be05292e3e1f8a51218827168cdclaireho { 17305569331642446be05292e3e1f8a51218827168cdclaireho new_offset += base_offset; 17315569331642446be05292e3e1f8a51218827168cdclaireho 17325569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 17335569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 17345569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_Anchor( &eer[n].ExitAnchor, 17355569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 17365569331642446be05292e3e1f8a51218827168cdclaireho { 17375569331642446be05292e3e1f8a51218827168cdclaireho if ( entry_offset ) 17385569331642446be05292e3e1f8a51218827168cdclaireho Free_Anchor( &eer[n].EntryAnchor ); 17395569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 17405569331642446be05292e3e1f8a51218827168cdclaireho } 17415569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 17425569331642446be05292e3e1f8a51218827168cdclaireho } 17435569331642446be05292e3e1f8a51218827168cdclaireho else 17445569331642446be05292e3e1f8a51218827168cdclaireho eer[n].ExitAnchor.PosFormat = 0; 17455569331642446be05292e3e1f8a51218827168cdclaireho } 17465569331642446be05292e3e1f8a51218827168cdclaireho 17475569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 17485569331642446be05292e3e1f8a51218827168cdclaireho 17495569331642446be05292e3e1f8a51218827168cdclairehoFail1: 17505569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; m++ ) 17515569331642446be05292e3e1f8a51218827168cdclaireho { 17525569331642446be05292e3e1f8a51218827168cdclaireho Free_Anchor( &eer[m].EntryAnchor ); 17535569331642446be05292e3e1f8a51218827168cdclaireho Free_Anchor( &eer[m].ExitAnchor ); 17545569331642446be05292e3e1f8a51218827168cdclaireho } 17555569331642446be05292e3e1f8a51218827168cdclaireho 17565569331642446be05292e3e1f8a51218827168cdclaireho FREE( eer ); 17575569331642446be05292e3e1f8a51218827168cdclaireho 17585569331642446be05292e3e1f8a51218827168cdclairehoFail2: 17595569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &cp->Coverage ); 17605569331642446be05292e3e1f8a51218827168cdclaireho return error; 17615569331642446be05292e3e1f8a51218827168cdclaireho} 17625569331642446be05292e3e1f8a51218827168cdclaireho 17635569331642446be05292e3e1f8a51218827168cdclaireho 17645569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_CursivePos( HB_GPOS_SubTable* st ) 17655569331642446be05292e3e1f8a51218827168cdclaireho{ 17665569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 17675569331642446be05292e3e1f8a51218827168cdclaireho HB_CursivePos* cp = &st->cursive; 17685569331642446be05292e3e1f8a51218827168cdclaireho 17695569331642446be05292e3e1f8a51218827168cdclaireho HB_EntryExitRecord* eer; 17705569331642446be05292e3e1f8a51218827168cdclaireho 17715569331642446be05292e3e1f8a51218827168cdclaireho 17725569331642446be05292e3e1f8a51218827168cdclaireho if ( cp->EntryExitRecord ) 17735569331642446be05292e3e1f8a51218827168cdclaireho { 17745569331642446be05292e3e1f8a51218827168cdclaireho count = cp->EntryExitCount; 17755569331642446be05292e3e1f8a51218827168cdclaireho eer = cp->EntryExitRecord; 17765569331642446be05292e3e1f8a51218827168cdclaireho 17775569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 17785569331642446be05292e3e1f8a51218827168cdclaireho { 17795569331642446be05292e3e1f8a51218827168cdclaireho Free_Anchor( &eer[n].EntryAnchor ); 17805569331642446be05292e3e1f8a51218827168cdclaireho Free_Anchor( &eer[n].ExitAnchor ); 17815569331642446be05292e3e1f8a51218827168cdclaireho } 17825569331642446be05292e3e1f8a51218827168cdclaireho 17835569331642446be05292e3e1f8a51218827168cdclaireho FREE( eer ); 17845569331642446be05292e3e1f8a51218827168cdclaireho } 17855569331642446be05292e3e1f8a51218827168cdclaireho 17865569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &cp->Coverage ); 17875569331642446be05292e3e1f8a51218827168cdclaireho} 17885569331642446be05292e3e1f8a51218827168cdclaireho 17895569331642446be05292e3e1f8a51218827168cdclaireho 17905569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Lookup_CursivePos( GPOS_Instance* gpi, 17915569331642446be05292e3e1f8a51218827168cdclaireho HB_GPOS_SubTable* st, 17925569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 17935569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort flags, 17945569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 17955569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 17965569331642446be05292e3e1f8a51218827168cdclaireho{ 17975569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort index, property; 17985569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 17995569331642446be05292e3e1f8a51218827168cdclaireho HB_GPOSHeader* gpos = gpi->gpos; 18005569331642446be05292e3e1f8a51218827168cdclaireho HB_CursivePos* cp = &st->cursive; 18015569331642446be05292e3e1f8a51218827168cdclaireho 18025569331642446be05292e3e1f8a51218827168cdclaireho HB_EntryExitRecord* eer; 18035569331642446be05292e3e1f8a51218827168cdclaireho HB_Fixed entry_x, entry_y; 18045569331642446be05292e3e1f8a51218827168cdclaireho HB_Fixed exit_x, exit_y; 18055569331642446be05292e3e1f8a51218827168cdclaireho 18065569331642446be05292e3e1f8a51218827168cdclaireho HB_UNUSED(nesting_level); 18075569331642446be05292e3e1f8a51218827168cdclaireho 18085569331642446be05292e3e1f8a51218827168cdclaireho if ( context_length != 0xFFFF && context_length < 1 ) 18095569331642446be05292e3e1f8a51218827168cdclaireho { 18105569331642446be05292e3e1f8a51218827168cdclaireho gpi->last = 0xFFFF; 18115569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 18125569331642446be05292e3e1f8a51218827168cdclaireho } 18135569331642446be05292e3e1f8a51218827168cdclaireho 18145569331642446be05292e3e1f8a51218827168cdclaireho /* Glyphs not having the right GDEF properties will be ignored, i.e., 18155569331642446be05292e3e1f8a51218827168cdclaireho gpi->last won't be reset (contrary to user defined properties). */ 18165569331642446be05292e3e1f8a51218827168cdclaireho 18175569331642446be05292e3e1f8a51218827168cdclaireho if ( CHECK_Property( gpos->gdef, IN_CURITEM(), flags, &property ) ) 18185569331642446be05292e3e1f8a51218827168cdclaireho return error; 18195569331642446be05292e3e1f8a51218827168cdclaireho 18205569331642446be05292e3e1f8a51218827168cdclaireho /* We don't handle mark glyphs here. According to Andrei, this isn't 18215569331642446be05292e3e1f8a51218827168cdclaireho possible, but who knows... */ 18225569331642446be05292e3e1f8a51218827168cdclaireho 18235569331642446be05292e3e1f8a51218827168cdclaireho if ( property == HB_GDEF_MARK ) 18245569331642446be05292e3e1f8a51218827168cdclaireho { 18255569331642446be05292e3e1f8a51218827168cdclaireho gpi->last = 0xFFFF; 18265569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 18275569331642446be05292e3e1f8a51218827168cdclaireho } 18285569331642446be05292e3e1f8a51218827168cdclaireho 18295569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &cp->Coverage, IN_CURGLYPH(), &index ); 18305569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 18315569331642446be05292e3e1f8a51218827168cdclaireho { 18325569331642446be05292e3e1f8a51218827168cdclaireho gpi->last = 0xFFFF; 18335569331642446be05292e3e1f8a51218827168cdclaireho return error; 18345569331642446be05292e3e1f8a51218827168cdclaireho } 18355569331642446be05292e3e1f8a51218827168cdclaireho 18365569331642446be05292e3e1f8a51218827168cdclaireho if ( index >= cp->EntryExitCount ) 18375569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable); 18385569331642446be05292e3e1f8a51218827168cdclaireho 18395569331642446be05292e3e1f8a51218827168cdclaireho eer = &cp->EntryExitRecord[index]; 18405569331642446be05292e3e1f8a51218827168cdclaireho 18415569331642446be05292e3e1f8a51218827168cdclaireho /* Now comes the messiest part of the whole OpenType 18425569331642446be05292e3e1f8a51218827168cdclaireho specification. At first glance, cursive connections seem easy 18435569331642446be05292e3e1f8a51218827168cdclaireho to understand, but there are pitfalls! The reason is that 18445569331642446be05292e3e1f8a51218827168cdclaireho the specs don't mention how to compute the advance values 18455569331642446be05292e3e1f8a51218827168cdclaireho resp. glyph offsets. I was told it would be an omission, to 18465569331642446be05292e3e1f8a51218827168cdclaireho be fixed in the next OpenType version... Again many thanks to 18475569331642446be05292e3e1f8a51218827168cdclaireho Andrei Burago <andreib@microsoft.com> for clarifications. 18485569331642446be05292e3e1f8a51218827168cdclaireho 18495569331642446be05292e3e1f8a51218827168cdclaireho Consider the following example: 18505569331642446be05292e3e1f8a51218827168cdclaireho 18515569331642446be05292e3e1f8a51218827168cdclaireho | xadv1 | 18525569331642446be05292e3e1f8a51218827168cdclaireho +---------+ 18535569331642446be05292e3e1f8a51218827168cdclaireho | | 18545569331642446be05292e3e1f8a51218827168cdclaireho +-----+--+ 1 | 18555569331642446be05292e3e1f8a51218827168cdclaireho | | .| | 18565569331642446be05292e3e1f8a51218827168cdclaireho | 0+--+------+ 18575569331642446be05292e3e1f8a51218827168cdclaireho | 2 | 18585569331642446be05292e3e1f8a51218827168cdclaireho | | 18595569331642446be05292e3e1f8a51218827168cdclaireho 0+--------+ 18605569331642446be05292e3e1f8a51218827168cdclaireho | xadv2 | 18615569331642446be05292e3e1f8a51218827168cdclaireho 18625569331642446be05292e3e1f8a51218827168cdclaireho glyph1: advance width = 12 18635569331642446be05292e3e1f8a51218827168cdclaireho anchor point = (3,1) 18645569331642446be05292e3e1f8a51218827168cdclaireho 18655569331642446be05292e3e1f8a51218827168cdclaireho glyph2: advance width = 11 18665569331642446be05292e3e1f8a51218827168cdclaireho anchor point = (9,4) 18675569331642446be05292e3e1f8a51218827168cdclaireho 18685569331642446be05292e3e1f8a51218827168cdclaireho LSB is 1 for both glyphs (so the boxes drawn above are glyph 18695569331642446be05292e3e1f8a51218827168cdclaireho bboxes). Writing direction is R2L; `0' denotes the glyph's 18705569331642446be05292e3e1f8a51218827168cdclaireho coordinate origin. 18715569331642446be05292e3e1f8a51218827168cdclaireho 18725569331642446be05292e3e1f8a51218827168cdclaireho Now the surprising part: The advance width of the *left* glyph 18735569331642446be05292e3e1f8a51218827168cdclaireho (resp. of the *bottom* glyph) will be modified, no matter 18745569331642446be05292e3e1f8a51218827168cdclaireho whether the writing direction is L2R or R2L (resp. T2B or 18755569331642446be05292e3e1f8a51218827168cdclaireho B2T)! This assymetry is caused by the fact that the glyph's 18765569331642446be05292e3e1f8a51218827168cdclaireho coordinate origin is always the lower left corner for all 18775569331642446be05292e3e1f8a51218827168cdclaireho writing directions. 18785569331642446be05292e3e1f8a51218827168cdclaireho 18795569331642446be05292e3e1f8a51218827168cdclaireho Continuing the above example, we can compute the new 18805569331642446be05292e3e1f8a51218827168cdclaireho (horizontal) advance width of glyph2 as 18815569331642446be05292e3e1f8a51218827168cdclaireho 18825569331642446be05292e3e1f8a51218827168cdclaireho 9 - 3 = 6 , 18835569331642446be05292e3e1f8a51218827168cdclaireho 18845569331642446be05292e3e1f8a51218827168cdclaireho and the new vertical offset of glyph2 as 18855569331642446be05292e3e1f8a51218827168cdclaireho 18865569331642446be05292e3e1f8a51218827168cdclaireho 1 - 4 = -3 . 18875569331642446be05292e3e1f8a51218827168cdclaireho 18885569331642446be05292e3e1f8a51218827168cdclaireho 18895569331642446be05292e3e1f8a51218827168cdclaireho Vertical writing direction is far more complicated: 18905569331642446be05292e3e1f8a51218827168cdclaireho 18915569331642446be05292e3e1f8a51218827168cdclaireho a) Assuming that we recompute the advance height of the lower glyph: 18925569331642446be05292e3e1f8a51218827168cdclaireho 18935569331642446be05292e3e1f8a51218827168cdclaireho -- 18945569331642446be05292e3e1f8a51218827168cdclaireho +---------+ 18955569331642446be05292e3e1f8a51218827168cdclaireho -- | | 18965569331642446be05292e3e1f8a51218827168cdclaireho +-----+--+ 1 | yadv1 18975569331642446be05292e3e1f8a51218827168cdclaireho | | .| | 18985569331642446be05292e3e1f8a51218827168cdclaireho yadv2 | 0+--+------+ -- BSB1 -- 18995569331642446be05292e3e1f8a51218827168cdclaireho | 2 | -- -- y_offset 19005569331642446be05292e3e1f8a51218827168cdclaireho | | 19015569331642446be05292e3e1f8a51218827168cdclaireho BSB2 -- 0+--------+ -- 19025569331642446be05292e3e1f8a51218827168cdclaireho -- -- 19035569331642446be05292e3e1f8a51218827168cdclaireho 19045569331642446be05292e3e1f8a51218827168cdclaireho glyph1: advance height = 6 19055569331642446be05292e3e1f8a51218827168cdclaireho anchor point = (3,1) 19065569331642446be05292e3e1f8a51218827168cdclaireho 19075569331642446be05292e3e1f8a51218827168cdclaireho glyph2: advance height = 7 19085569331642446be05292e3e1f8a51218827168cdclaireho anchor point = (9,4) 19095569331642446be05292e3e1f8a51218827168cdclaireho 19105569331642446be05292e3e1f8a51218827168cdclaireho TSB is 1 for both glyphs; writing direction is T2B. 19115569331642446be05292e3e1f8a51218827168cdclaireho 19125569331642446be05292e3e1f8a51218827168cdclaireho 19135569331642446be05292e3e1f8a51218827168cdclaireho BSB1 = yadv1 - (TSB1 + ymax1) 19145569331642446be05292e3e1f8a51218827168cdclaireho BSB2 = yadv2 - (TSB2 + ymax2) 19155569331642446be05292e3e1f8a51218827168cdclaireho y_offset = y2 - y1 19165569331642446be05292e3e1f8a51218827168cdclaireho 19175569331642446be05292e3e1f8a51218827168cdclaireho vertical advance width of glyph2 19185569331642446be05292e3e1f8a51218827168cdclaireho = y_offset + BSB2 - BSB1 19195569331642446be05292e3e1f8a51218827168cdclaireho = (y2 - y1) + (yadv2 - (TSB2 + ymax2)) - (yadv1 - (TSB1 + ymax1)) 19205569331642446be05292e3e1f8a51218827168cdclaireho = y2 - y1 + yadv2 - TSB2 - ymax2 - (yadv1 - TSB1 - ymax1) 19215569331642446be05292e3e1f8a51218827168cdclaireho = y2 - y1 + yadv2 - TSB2 - ymax2 - yadv1 + TSB1 + ymax1 19225569331642446be05292e3e1f8a51218827168cdclaireho 19235569331642446be05292e3e1f8a51218827168cdclaireho 19245569331642446be05292e3e1f8a51218827168cdclaireho b) Assuming that we recompute the advance height of the upper glyph: 19255569331642446be05292e3e1f8a51218827168cdclaireho 19265569331642446be05292e3e1f8a51218827168cdclaireho -- -- 19275569331642446be05292e3e1f8a51218827168cdclaireho +---------+ -- TSB1 19285569331642446be05292e3e1f8a51218827168cdclaireho -- -- | | 19295569331642446be05292e3e1f8a51218827168cdclaireho TSB2 -- +-----+--+ 1 | yadv1 ymax1 19305569331642446be05292e3e1f8a51218827168cdclaireho | | .| | 19315569331642446be05292e3e1f8a51218827168cdclaireho yadv2 | 0+--+------+ -- -- 19325569331642446be05292e3e1f8a51218827168cdclaireho ymax2 | 2 | -- y_offset 19335569331642446be05292e3e1f8a51218827168cdclaireho | | 19345569331642446be05292e3e1f8a51218827168cdclaireho -- 0+--------+ -- 19355569331642446be05292e3e1f8a51218827168cdclaireho -- 19365569331642446be05292e3e1f8a51218827168cdclaireho 19375569331642446be05292e3e1f8a51218827168cdclaireho glyph1: advance height = 6 19385569331642446be05292e3e1f8a51218827168cdclaireho anchor point = (3,1) 19395569331642446be05292e3e1f8a51218827168cdclaireho 19405569331642446be05292e3e1f8a51218827168cdclaireho glyph2: advance height = 7 19415569331642446be05292e3e1f8a51218827168cdclaireho anchor point = (9,4) 19425569331642446be05292e3e1f8a51218827168cdclaireho 19435569331642446be05292e3e1f8a51218827168cdclaireho TSB is 1 for both glyphs; writing direction is T2B. 19445569331642446be05292e3e1f8a51218827168cdclaireho 19455569331642446be05292e3e1f8a51218827168cdclaireho y_offset = y2 - y1 19465569331642446be05292e3e1f8a51218827168cdclaireho 19475569331642446be05292e3e1f8a51218827168cdclaireho vertical advance width of glyph2 19485569331642446be05292e3e1f8a51218827168cdclaireho = TSB1 + ymax1 + y_offset - (TSB2 + ymax2) 19495569331642446be05292e3e1f8a51218827168cdclaireho = TSB1 + ymax1 + y2 - y1 - TSB2 - ymax2 19505569331642446be05292e3e1f8a51218827168cdclaireho 19515569331642446be05292e3e1f8a51218827168cdclaireho 19525569331642446be05292e3e1f8a51218827168cdclaireho Comparing a) with b) shows that b) is easier to compute. I'll wait 19535569331642446be05292e3e1f8a51218827168cdclaireho for a reply from Andrei to see what should really be implemented... 19545569331642446be05292e3e1f8a51218827168cdclaireho 19555569331642446be05292e3e1f8a51218827168cdclaireho Since horizontal advance widths or vertical advance heights 19565569331642446be05292e3e1f8a51218827168cdclaireho can be used alone but not together, no ambiguity occurs. */ 19575569331642446be05292e3e1f8a51218827168cdclaireho 19585569331642446be05292e3e1f8a51218827168cdclaireho if ( gpi->last == 0xFFFF ) 19595569331642446be05292e3e1f8a51218827168cdclaireho goto end; 19605569331642446be05292e3e1f8a51218827168cdclaireho 19615569331642446be05292e3e1f8a51218827168cdclaireho /* Get_Anchor() returns HB_Err_Not_Covered if there is no anchor 19625569331642446be05292e3e1f8a51218827168cdclaireho table. */ 19635569331642446be05292e3e1f8a51218827168cdclaireho 19645569331642446be05292e3e1f8a51218827168cdclaireho error = Get_Anchor( gpi, &eer->EntryAnchor, IN_CURGLYPH(), 19655569331642446be05292e3e1f8a51218827168cdclaireho &entry_x, &entry_y ); 19665569331642446be05292e3e1f8a51218827168cdclaireho if ( error == HB_Err_Not_Covered ) 19675569331642446be05292e3e1f8a51218827168cdclaireho goto end; 19685569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 19695569331642446be05292e3e1f8a51218827168cdclaireho return error; 19705569331642446be05292e3e1f8a51218827168cdclaireho 19715569331642446be05292e3e1f8a51218827168cdclaireho if ( gpi->r2l ) 19725569331642446be05292e3e1f8a51218827168cdclaireho { 19735569331642446be05292e3e1f8a51218827168cdclaireho POSITION( buffer->in_pos )->x_advance = entry_x - gpi->anchor_x; 19745569331642446be05292e3e1f8a51218827168cdclaireho POSITION( buffer->in_pos )->new_advance = TRUE; 19755569331642446be05292e3e1f8a51218827168cdclaireho } 19765569331642446be05292e3e1f8a51218827168cdclaireho else 19775569331642446be05292e3e1f8a51218827168cdclaireho { 19785569331642446be05292e3e1f8a51218827168cdclaireho POSITION( gpi->last )->x_advance = gpi->anchor_x - entry_x; 19795569331642446be05292e3e1f8a51218827168cdclaireho POSITION( gpi->last )->new_advance = TRUE; 19805569331642446be05292e3e1f8a51218827168cdclaireho } 19815569331642446be05292e3e1f8a51218827168cdclaireho 19825569331642446be05292e3e1f8a51218827168cdclaireho if ( flags & HB_LOOKUP_FLAG_RIGHT_TO_LEFT ) 19835569331642446be05292e3e1f8a51218827168cdclaireho { 19845569331642446be05292e3e1f8a51218827168cdclaireho POSITION( gpi->last )->cursive_chain = gpi->last - buffer->in_pos; 19855569331642446be05292e3e1f8a51218827168cdclaireho POSITION( gpi->last )->y_pos = entry_y - gpi->anchor_y; 19865569331642446be05292e3e1f8a51218827168cdclaireho } 19875569331642446be05292e3e1f8a51218827168cdclaireho else 19885569331642446be05292e3e1f8a51218827168cdclaireho { 19895569331642446be05292e3e1f8a51218827168cdclaireho POSITION( buffer->in_pos )->cursive_chain = buffer->in_pos - gpi->last; 19905569331642446be05292e3e1f8a51218827168cdclaireho POSITION( buffer->in_pos )->y_pos = gpi->anchor_y - entry_y; 19915569331642446be05292e3e1f8a51218827168cdclaireho } 19925569331642446be05292e3e1f8a51218827168cdclaireho 19935569331642446be05292e3e1f8a51218827168cdclairehoend: 19945569331642446be05292e3e1f8a51218827168cdclaireho error = Get_Anchor( gpi, &eer->ExitAnchor, IN_CURGLYPH(), 19955569331642446be05292e3e1f8a51218827168cdclaireho &exit_x, &exit_y ); 19965569331642446be05292e3e1f8a51218827168cdclaireho if ( error == HB_Err_Not_Covered ) 19975569331642446be05292e3e1f8a51218827168cdclaireho gpi->last = 0xFFFF; 19985569331642446be05292e3e1f8a51218827168cdclaireho else 19995569331642446be05292e3e1f8a51218827168cdclaireho { 20005569331642446be05292e3e1f8a51218827168cdclaireho gpi->last = buffer->in_pos; 20015569331642446be05292e3e1f8a51218827168cdclaireho gpi->anchor_x = exit_x; 20025569331642446be05292e3e1f8a51218827168cdclaireho gpi->anchor_y = exit_y; 20035569331642446be05292e3e1f8a51218827168cdclaireho } 20045569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 20055569331642446be05292e3e1f8a51218827168cdclaireho return error; 20065569331642446be05292e3e1f8a51218827168cdclaireho 20075569331642446be05292e3e1f8a51218827168cdclaireho (buffer->in_pos)++; 20085569331642446be05292e3e1f8a51218827168cdclaireho 20095569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 20105569331642446be05292e3e1f8a51218827168cdclaireho} 20115569331642446be05292e3e1f8a51218827168cdclaireho 20125569331642446be05292e3e1f8a51218827168cdclaireho 20135569331642446be05292e3e1f8a51218827168cdclaireho/* LookupType 4 */ 20145569331642446be05292e3e1f8a51218827168cdclaireho 20155569331642446be05292e3e1f8a51218827168cdclaireho/* BaseArray */ 20165569331642446be05292e3e1f8a51218827168cdclaireho 20175569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_BaseArray( HB_BaseArray* ba, 20185569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort num_classes, 20195569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 20205569331642446be05292e3e1f8a51218827168cdclaireho{ 20215569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 20225569331642446be05292e3e1f8a51218827168cdclaireho 20235569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort m, n, count; 20245569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 20255569331642446be05292e3e1f8a51218827168cdclaireho 20265569331642446be05292e3e1f8a51218827168cdclaireho HB_BaseRecord *br; 20275569331642446be05292e3e1f8a51218827168cdclaireho HB_Anchor *ban, *bans; 20285569331642446be05292e3e1f8a51218827168cdclaireho 20295569331642446be05292e3e1f8a51218827168cdclaireho 20305569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 20315569331642446be05292e3e1f8a51218827168cdclaireho 20325569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 20335569331642446be05292e3e1f8a51218827168cdclaireho return error; 20345569331642446be05292e3e1f8a51218827168cdclaireho 20355569331642446be05292e3e1f8a51218827168cdclaireho count = ba->BaseCount = GET_UShort(); 20365569331642446be05292e3e1f8a51218827168cdclaireho 20375569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 20385569331642446be05292e3e1f8a51218827168cdclaireho 20395569331642446be05292e3e1f8a51218827168cdclaireho ba->BaseRecord = NULL; 20405569331642446be05292e3e1f8a51218827168cdclaireho 20415569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( ba->BaseRecord, count, HB_BaseRecord ) ) 20425569331642446be05292e3e1f8a51218827168cdclaireho return error; 20435569331642446be05292e3e1f8a51218827168cdclaireho 20445569331642446be05292e3e1f8a51218827168cdclaireho br = ba->BaseRecord; 20455569331642446be05292e3e1f8a51218827168cdclaireho 20465569331642446be05292e3e1f8a51218827168cdclaireho bans = NULL; 20475569331642446be05292e3e1f8a51218827168cdclaireho 20485569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( bans, count * num_classes, HB_Anchor ) ) 20495569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 20505569331642446be05292e3e1f8a51218827168cdclaireho 20515569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < count; m++ ) 20525569331642446be05292e3e1f8a51218827168cdclaireho { 20535569331642446be05292e3e1f8a51218827168cdclaireho br[m].BaseAnchor = NULL; 20545569331642446be05292e3e1f8a51218827168cdclaireho 20555569331642446be05292e3e1f8a51218827168cdclaireho ban = br[m].BaseAnchor = bans + m * num_classes; 20565569331642446be05292e3e1f8a51218827168cdclaireho 20575569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < num_classes; n++ ) 20585569331642446be05292e3e1f8a51218827168cdclaireho { 20595569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 20605569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 20615569331642446be05292e3e1f8a51218827168cdclaireho 20625569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 20635569331642446be05292e3e1f8a51218827168cdclaireho 20645569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 20655569331642446be05292e3e1f8a51218827168cdclaireho 20665569331642446be05292e3e1f8a51218827168cdclaireho if (new_offset == base_offset) { 20675569331642446be05292e3e1f8a51218827168cdclaireho /* XXX 20685569331642446be05292e3e1f8a51218827168cdclaireho * Doulos SIL Regular is buggy and has zero offsets here. 20695569331642446be05292e3e1f8a51218827168cdclaireho * Skip it 20705569331642446be05292e3e1f8a51218827168cdclaireho */ 20715569331642446be05292e3e1f8a51218827168cdclaireho ban[n].PosFormat = 0; 20725569331642446be05292e3e1f8a51218827168cdclaireho continue; 20735569331642446be05292e3e1f8a51218827168cdclaireho } 20745569331642446be05292e3e1f8a51218827168cdclaireho 20755569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 20765569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 20775569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_Anchor( &ban[n], stream ) ) != HB_Err_Ok ) 20785569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 20795569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 20805569331642446be05292e3e1f8a51218827168cdclaireho } 20815569331642446be05292e3e1f8a51218827168cdclaireho } 20825569331642446be05292e3e1f8a51218827168cdclaireho 20835569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 20845569331642446be05292e3e1f8a51218827168cdclaireho 20855569331642446be05292e3e1f8a51218827168cdclairehoFail: 20865569331642446be05292e3e1f8a51218827168cdclaireho FREE( bans ); 20875569331642446be05292e3e1f8a51218827168cdclaireho FREE( br ); 20885569331642446be05292e3e1f8a51218827168cdclaireho return error; 20895569331642446be05292e3e1f8a51218827168cdclaireho} 20905569331642446be05292e3e1f8a51218827168cdclaireho 20915569331642446be05292e3e1f8a51218827168cdclaireho 20925569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_BaseArray( HB_BaseArray* ba, 20935569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort num_classes ) 20945569331642446be05292e3e1f8a51218827168cdclaireho{ 20955569331642446be05292e3e1f8a51218827168cdclaireho HB_BaseRecord *br; 20965569331642446be05292e3e1f8a51218827168cdclaireho HB_Anchor *bans; 20975569331642446be05292e3e1f8a51218827168cdclaireho 20985569331642446be05292e3e1f8a51218827168cdclaireho if ( ba->BaseRecord ) 20995569331642446be05292e3e1f8a51218827168cdclaireho { 21005569331642446be05292e3e1f8a51218827168cdclaireho br = ba->BaseRecord; 21015569331642446be05292e3e1f8a51218827168cdclaireho 21025569331642446be05292e3e1f8a51218827168cdclaireho if ( ba->BaseCount ) 21035569331642446be05292e3e1f8a51218827168cdclaireho { 21045569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort i, count; 21055569331642446be05292e3e1f8a51218827168cdclaireho count = num_classes * ba->BaseCount; 21065569331642446be05292e3e1f8a51218827168cdclaireho bans = br[0].BaseAnchor; 21075569331642446be05292e3e1f8a51218827168cdclaireho for (i = 0; i < count; i++) 21085569331642446be05292e3e1f8a51218827168cdclaireho Free_Anchor (&bans[i]); 21095569331642446be05292e3e1f8a51218827168cdclaireho FREE( bans ); 21105569331642446be05292e3e1f8a51218827168cdclaireho } 21115569331642446be05292e3e1f8a51218827168cdclaireho 21125569331642446be05292e3e1f8a51218827168cdclaireho FREE( br ); 21135569331642446be05292e3e1f8a51218827168cdclaireho } 21145569331642446be05292e3e1f8a51218827168cdclaireho} 21155569331642446be05292e3e1f8a51218827168cdclaireho 21165569331642446be05292e3e1f8a51218827168cdclaireho 21175569331642446be05292e3e1f8a51218827168cdclaireho/* MarkBasePosFormat1 */ 21185569331642446be05292e3e1f8a51218827168cdclaireho 21195569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_MarkBasePos( HB_GPOS_SubTable* st, 21205569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 21215569331642446be05292e3e1f8a51218827168cdclaireho{ 21225569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 21235569331642446be05292e3e1f8a51218827168cdclaireho HB_MarkBasePos* mbp = &st->markbase; 21245569331642446be05292e3e1f8a51218827168cdclaireho 21255569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 21265569331642446be05292e3e1f8a51218827168cdclaireho 21275569331642446be05292e3e1f8a51218827168cdclaireho 21285569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 21295569331642446be05292e3e1f8a51218827168cdclaireho 21305569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 4L ) ) 21315569331642446be05292e3e1f8a51218827168cdclaireho return error; 21325569331642446be05292e3e1f8a51218827168cdclaireho 21335569331642446be05292e3e1f8a51218827168cdclaireho mbp->PosFormat = GET_UShort(); 21345569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 21355569331642446be05292e3e1f8a51218827168cdclaireho 21365569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 21375569331642446be05292e3e1f8a51218827168cdclaireho 21385569331642446be05292e3e1f8a51218827168cdclaireho if (mbp->PosFormat != 1) 21395569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable_Format); 21405569331642446be05292e3e1f8a51218827168cdclaireho 21415569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 21425569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 21435569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &mbp->MarkCoverage, stream ) ) != HB_Err_Ok ) 21445569331642446be05292e3e1f8a51218827168cdclaireho return error; 21455569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 21465569331642446be05292e3e1f8a51218827168cdclaireho 21475569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 21485569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 21495569331642446be05292e3e1f8a51218827168cdclaireho 21505569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 21515569331642446be05292e3e1f8a51218827168cdclaireho 21525569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 21535569331642446be05292e3e1f8a51218827168cdclaireho 21545569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 21555569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 21565569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &mbp->BaseCoverage, stream ) ) != HB_Err_Ok ) 21575569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 21585569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 21595569331642446be05292e3e1f8a51218827168cdclaireho 21605569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 4L ) ) 21615569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 21625569331642446be05292e3e1f8a51218827168cdclaireho 21635569331642446be05292e3e1f8a51218827168cdclaireho mbp->ClassCount = GET_UShort(); 21645569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 21655569331642446be05292e3e1f8a51218827168cdclaireho 21665569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 21675569331642446be05292e3e1f8a51218827168cdclaireho 21685569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 21695569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 21705569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_MarkArray( &mbp->MarkArray, stream ) ) != HB_Err_Ok ) 21715569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 21725569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 21735569331642446be05292e3e1f8a51218827168cdclaireho 21745569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 21755569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 21765569331642446be05292e3e1f8a51218827168cdclaireho 21775569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 21785569331642446be05292e3e1f8a51218827168cdclaireho 21795569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 21805569331642446be05292e3e1f8a51218827168cdclaireho 21815569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 21825569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 21835569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_BaseArray( &mbp->BaseArray, mbp->ClassCount, 21845569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 21855569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 21865569331642446be05292e3e1f8a51218827168cdclaireho 21875569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 21885569331642446be05292e3e1f8a51218827168cdclaireho 21895569331642446be05292e3e1f8a51218827168cdclairehoFail1: 21905569331642446be05292e3e1f8a51218827168cdclaireho Free_MarkArray( &mbp->MarkArray ); 21915569331642446be05292e3e1f8a51218827168cdclaireho 21925569331642446be05292e3e1f8a51218827168cdclairehoFail2: 21935569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &mbp->BaseCoverage ); 21945569331642446be05292e3e1f8a51218827168cdclaireho 21955569331642446be05292e3e1f8a51218827168cdclairehoFail3: 21965569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &mbp->MarkCoverage ); 21975569331642446be05292e3e1f8a51218827168cdclaireho return error; 21985569331642446be05292e3e1f8a51218827168cdclaireho} 21995569331642446be05292e3e1f8a51218827168cdclaireho 22005569331642446be05292e3e1f8a51218827168cdclaireho 22015569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_MarkBasePos( HB_GPOS_SubTable* st ) 22025569331642446be05292e3e1f8a51218827168cdclaireho{ 22035569331642446be05292e3e1f8a51218827168cdclaireho HB_MarkBasePos* mbp = &st->markbase; 22045569331642446be05292e3e1f8a51218827168cdclaireho 22055569331642446be05292e3e1f8a51218827168cdclaireho Free_BaseArray( &mbp->BaseArray, mbp->ClassCount ); 22065569331642446be05292e3e1f8a51218827168cdclaireho Free_MarkArray( &mbp->MarkArray ); 22075569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &mbp->BaseCoverage ); 22085569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &mbp->MarkCoverage ); 22095569331642446be05292e3e1f8a51218827168cdclaireho} 22105569331642446be05292e3e1f8a51218827168cdclaireho 22115569331642446be05292e3e1f8a51218827168cdclaireho 22125569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Lookup_MarkBasePos( GPOS_Instance* gpi, 22135569331642446be05292e3e1f8a51218827168cdclaireho HB_GPOS_SubTable* st, 22145569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 22155569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort flags, 22165569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 22175569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 22185569331642446be05292e3e1f8a51218827168cdclaireho{ 22195569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort i, j, mark_index, base_index, property, class; 22205569331642446be05292e3e1f8a51218827168cdclaireho HB_Fixed x_mark_value, y_mark_value, x_base_value, y_base_value; 22215569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 22225569331642446be05292e3e1f8a51218827168cdclaireho HB_GPOSHeader* gpos = gpi->gpos; 22235569331642446be05292e3e1f8a51218827168cdclaireho HB_MarkBasePos* mbp = &st->markbase; 22245569331642446be05292e3e1f8a51218827168cdclaireho 22255569331642446be05292e3e1f8a51218827168cdclaireho HB_MarkArray* ma; 22265569331642446be05292e3e1f8a51218827168cdclaireho HB_BaseArray* ba; 22275569331642446be05292e3e1f8a51218827168cdclaireho HB_BaseRecord* br; 22285569331642446be05292e3e1f8a51218827168cdclaireho HB_Anchor* mark_anchor; 22295569331642446be05292e3e1f8a51218827168cdclaireho HB_Anchor* base_anchor; 22305569331642446be05292e3e1f8a51218827168cdclaireho 22315569331642446be05292e3e1f8a51218827168cdclaireho HB_Position o; 22325569331642446be05292e3e1f8a51218827168cdclaireho 22335569331642446be05292e3e1f8a51218827168cdclaireho HB_UNUSED(nesting_level); 22345569331642446be05292e3e1f8a51218827168cdclaireho 22355569331642446be05292e3e1f8a51218827168cdclaireho if ( context_length != 0xFFFF && context_length < 1 ) 22365569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 22375569331642446be05292e3e1f8a51218827168cdclaireho 22385569331642446be05292e3e1f8a51218827168cdclaireho if ( flags & HB_LOOKUP_FLAG_IGNORE_BASE_GLYPHS ) 22395569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 22405569331642446be05292e3e1f8a51218827168cdclaireho 22415569331642446be05292e3e1f8a51218827168cdclaireho if ( CHECK_Property( gpos->gdef, IN_CURITEM(), 22425569331642446be05292e3e1f8a51218827168cdclaireho flags, &property ) ) 22435569331642446be05292e3e1f8a51218827168cdclaireho return error; 22445569331642446be05292e3e1f8a51218827168cdclaireho 22455569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &mbp->MarkCoverage, IN_CURGLYPH(), 22465569331642446be05292e3e1f8a51218827168cdclaireho &mark_index ); 22475569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 22485569331642446be05292e3e1f8a51218827168cdclaireho return error; 22495569331642446be05292e3e1f8a51218827168cdclaireho 22505569331642446be05292e3e1f8a51218827168cdclaireho /* now we search backwards for a non-mark glyph */ 22515569331642446be05292e3e1f8a51218827168cdclaireho 22525569331642446be05292e3e1f8a51218827168cdclaireho i = 1; 22535569331642446be05292e3e1f8a51218827168cdclaireho j = buffer->in_pos - 1; 22545569331642446be05292e3e1f8a51218827168cdclaireho 22555569331642446be05292e3e1f8a51218827168cdclaireho while ( i <= buffer->in_pos ) 22565569331642446be05292e3e1f8a51218827168cdclaireho { 22575569331642446be05292e3e1f8a51218827168cdclaireho error = HB_GDEF_Get_Glyph_Property( gpos->gdef, IN_GLYPH( j ), 22585569331642446be05292e3e1f8a51218827168cdclaireho &property ); 22595569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 22605569331642446be05292e3e1f8a51218827168cdclaireho return error; 22615569331642446be05292e3e1f8a51218827168cdclaireho 22625569331642446be05292e3e1f8a51218827168cdclaireho if ( !( property == HB_GDEF_MARK || property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) ) 22635569331642446be05292e3e1f8a51218827168cdclaireho break; 22645569331642446be05292e3e1f8a51218827168cdclaireho 22655569331642446be05292e3e1f8a51218827168cdclaireho i++; 22665569331642446be05292e3e1f8a51218827168cdclaireho j--; 22675569331642446be05292e3e1f8a51218827168cdclaireho } 22685569331642446be05292e3e1f8a51218827168cdclaireho 22695569331642446be05292e3e1f8a51218827168cdclaireho /* The following assertion is too strong -- at least for mangal.ttf. */ 22705569331642446be05292e3e1f8a51218827168cdclaireho#if 0 22715569331642446be05292e3e1f8a51218827168cdclaireho if ( property != HB_GDEF_BASE_GLYPH ) 22725569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 22735569331642446be05292e3e1f8a51218827168cdclaireho#endif 22745569331642446be05292e3e1f8a51218827168cdclaireho 22755569331642446be05292e3e1f8a51218827168cdclaireho if ( i > buffer->in_pos ) 22765569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 22775569331642446be05292e3e1f8a51218827168cdclaireho 22785569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &mbp->BaseCoverage, IN_GLYPH( j ), 22795569331642446be05292e3e1f8a51218827168cdclaireho &base_index ); 22805569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 22815569331642446be05292e3e1f8a51218827168cdclaireho return error; 22825569331642446be05292e3e1f8a51218827168cdclaireho 22835569331642446be05292e3e1f8a51218827168cdclaireho ma = &mbp->MarkArray; 22845569331642446be05292e3e1f8a51218827168cdclaireho 22855569331642446be05292e3e1f8a51218827168cdclaireho if ( mark_index >= ma->MarkCount ) 22865569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable); 22875569331642446be05292e3e1f8a51218827168cdclaireho 22885569331642446be05292e3e1f8a51218827168cdclaireho class = ma->MarkRecord[mark_index].Class; 22895569331642446be05292e3e1f8a51218827168cdclaireho mark_anchor = &ma->MarkRecord[mark_index].MarkAnchor; 22905569331642446be05292e3e1f8a51218827168cdclaireho 22915569331642446be05292e3e1f8a51218827168cdclaireho if ( class >= mbp->ClassCount ) 22925569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable); 22935569331642446be05292e3e1f8a51218827168cdclaireho 22945569331642446be05292e3e1f8a51218827168cdclaireho ba = &mbp->BaseArray; 22955569331642446be05292e3e1f8a51218827168cdclaireho 22965569331642446be05292e3e1f8a51218827168cdclaireho if ( base_index >= ba->BaseCount ) 22975569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable); 22985569331642446be05292e3e1f8a51218827168cdclaireho 22995569331642446be05292e3e1f8a51218827168cdclaireho br = &ba->BaseRecord[base_index]; 23005569331642446be05292e3e1f8a51218827168cdclaireho base_anchor = &br->BaseAnchor[class]; 23015569331642446be05292e3e1f8a51218827168cdclaireho 23025569331642446be05292e3e1f8a51218827168cdclaireho error = Get_Anchor( gpi, mark_anchor, IN_CURGLYPH(), 23035569331642446be05292e3e1f8a51218827168cdclaireho &x_mark_value, &y_mark_value ); 23045569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 23055569331642446be05292e3e1f8a51218827168cdclaireho return error; 23065569331642446be05292e3e1f8a51218827168cdclaireho 23075569331642446be05292e3e1f8a51218827168cdclaireho error = Get_Anchor( gpi, base_anchor, IN_GLYPH( j ), 23085569331642446be05292e3e1f8a51218827168cdclaireho &x_base_value, &y_base_value ); 23095569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 23105569331642446be05292e3e1f8a51218827168cdclaireho return error; 23115569331642446be05292e3e1f8a51218827168cdclaireho 23125569331642446be05292e3e1f8a51218827168cdclaireho /* anchor points are not cumulative */ 23135569331642446be05292e3e1f8a51218827168cdclaireho 23145569331642446be05292e3e1f8a51218827168cdclaireho o = POSITION( buffer->in_pos ); 23155569331642446be05292e3e1f8a51218827168cdclaireho 23165569331642446be05292e3e1f8a51218827168cdclaireho o->x_pos = x_base_value - x_mark_value; 23175569331642446be05292e3e1f8a51218827168cdclaireho o->y_pos = y_base_value - y_mark_value; 23185569331642446be05292e3e1f8a51218827168cdclaireho o->x_advance = 0; 23195569331642446be05292e3e1f8a51218827168cdclaireho o->y_advance = 0; 23205569331642446be05292e3e1f8a51218827168cdclaireho o->back = i; 23215569331642446be05292e3e1f8a51218827168cdclaireho 23225569331642446be05292e3e1f8a51218827168cdclaireho (buffer->in_pos)++; 23235569331642446be05292e3e1f8a51218827168cdclaireho 23245569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 23255569331642446be05292e3e1f8a51218827168cdclaireho} 23265569331642446be05292e3e1f8a51218827168cdclaireho 23275569331642446be05292e3e1f8a51218827168cdclaireho 23285569331642446be05292e3e1f8a51218827168cdclaireho/* LookupType 5 */ 23295569331642446be05292e3e1f8a51218827168cdclaireho 23305569331642446be05292e3e1f8a51218827168cdclaireho/* LigatureAttach */ 23315569331642446be05292e3e1f8a51218827168cdclaireho 23325569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_LigatureAttach( HB_LigatureAttach* lat, 23335569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort num_classes, 23345569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 23355569331642446be05292e3e1f8a51218827168cdclaireho{ 23365569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 23375569331642446be05292e3e1f8a51218827168cdclaireho 23385569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort m, n, k, count; 23395569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 23405569331642446be05292e3e1f8a51218827168cdclaireho 23415569331642446be05292e3e1f8a51218827168cdclaireho HB_ComponentRecord* cr; 23425569331642446be05292e3e1f8a51218827168cdclaireho HB_Anchor* lan; 23435569331642446be05292e3e1f8a51218827168cdclaireho 23445569331642446be05292e3e1f8a51218827168cdclaireho 23455569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 23465569331642446be05292e3e1f8a51218827168cdclaireho 23475569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 23485569331642446be05292e3e1f8a51218827168cdclaireho return error; 23495569331642446be05292e3e1f8a51218827168cdclaireho 23505569331642446be05292e3e1f8a51218827168cdclaireho count = lat->ComponentCount = GET_UShort(); 23515569331642446be05292e3e1f8a51218827168cdclaireho 23525569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 23535569331642446be05292e3e1f8a51218827168cdclaireho 23545569331642446be05292e3e1f8a51218827168cdclaireho lat->ComponentRecord = NULL; 23555569331642446be05292e3e1f8a51218827168cdclaireho 23565569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( lat->ComponentRecord, count, HB_ComponentRecord ) ) 23575569331642446be05292e3e1f8a51218827168cdclaireho return error; 23585569331642446be05292e3e1f8a51218827168cdclaireho 23595569331642446be05292e3e1f8a51218827168cdclaireho cr = lat->ComponentRecord; 23605569331642446be05292e3e1f8a51218827168cdclaireho 23615569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < count; m++ ) 23625569331642446be05292e3e1f8a51218827168cdclaireho { 23635569331642446be05292e3e1f8a51218827168cdclaireho cr[m].LigatureAnchor = NULL; 23645569331642446be05292e3e1f8a51218827168cdclaireho 23655569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( cr[m].LigatureAnchor, num_classes, HB_Anchor ) ) 23665569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 23675569331642446be05292e3e1f8a51218827168cdclaireho 23685569331642446be05292e3e1f8a51218827168cdclaireho lan = cr[m].LigatureAnchor; 23695569331642446be05292e3e1f8a51218827168cdclaireho 23705569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < num_classes; n++ ) 23715569331642446be05292e3e1f8a51218827168cdclaireho { 23725569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 23735569331642446be05292e3e1f8a51218827168cdclaireho goto Fail0; 23745569331642446be05292e3e1f8a51218827168cdclaireho 23755569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort(); 23765569331642446be05292e3e1f8a51218827168cdclaireho 23775569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 23785569331642446be05292e3e1f8a51218827168cdclaireho 23795569331642446be05292e3e1f8a51218827168cdclaireho if ( new_offset ) 23805569331642446be05292e3e1f8a51218827168cdclaireho { 23815569331642446be05292e3e1f8a51218827168cdclaireho new_offset += base_offset; 23825569331642446be05292e3e1f8a51218827168cdclaireho 23835569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 23845569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 23855569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_Anchor( &lan[n], stream ) ) != HB_Err_Ok ) 23865569331642446be05292e3e1f8a51218827168cdclaireho goto Fail0; 23875569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 23885569331642446be05292e3e1f8a51218827168cdclaireho } 23895569331642446be05292e3e1f8a51218827168cdclaireho else 23905569331642446be05292e3e1f8a51218827168cdclaireho lan[n].PosFormat = 0; 23915569331642446be05292e3e1f8a51218827168cdclaireho } 23925569331642446be05292e3e1f8a51218827168cdclaireho 23935569331642446be05292e3e1f8a51218827168cdclaireho continue; 23945569331642446be05292e3e1f8a51218827168cdclaireho Fail0: 23955569331642446be05292e3e1f8a51218827168cdclaireho for ( k = 0; k < n; k++ ) 23965569331642446be05292e3e1f8a51218827168cdclaireho Free_Anchor( &lan[k] ); 23975569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 23985569331642446be05292e3e1f8a51218827168cdclaireho } 23995569331642446be05292e3e1f8a51218827168cdclaireho 24005569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 24015569331642446be05292e3e1f8a51218827168cdclaireho 24025569331642446be05292e3e1f8a51218827168cdclairehoFail: 24035569331642446be05292e3e1f8a51218827168cdclaireho for ( k = 0; k < m; k++ ) 24045569331642446be05292e3e1f8a51218827168cdclaireho { 24055569331642446be05292e3e1f8a51218827168cdclaireho lan = cr[k].LigatureAnchor; 24065569331642446be05292e3e1f8a51218827168cdclaireho 24075569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < num_classes; n++ ) 24085569331642446be05292e3e1f8a51218827168cdclaireho Free_Anchor( &lan[n] ); 24095569331642446be05292e3e1f8a51218827168cdclaireho 24105569331642446be05292e3e1f8a51218827168cdclaireho FREE( lan ); 24115569331642446be05292e3e1f8a51218827168cdclaireho } 24125569331642446be05292e3e1f8a51218827168cdclaireho 24135569331642446be05292e3e1f8a51218827168cdclaireho FREE( cr ); 24145569331642446be05292e3e1f8a51218827168cdclaireho return error; 24155569331642446be05292e3e1f8a51218827168cdclaireho} 24165569331642446be05292e3e1f8a51218827168cdclaireho 24175569331642446be05292e3e1f8a51218827168cdclaireho 24185569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_LigatureAttach( HB_LigatureAttach* lat, 24195569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort num_classes ) 24205569331642446be05292e3e1f8a51218827168cdclaireho{ 24215569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort m, n, count; 24225569331642446be05292e3e1f8a51218827168cdclaireho 24235569331642446be05292e3e1f8a51218827168cdclaireho HB_ComponentRecord* cr; 24245569331642446be05292e3e1f8a51218827168cdclaireho HB_Anchor* lan; 24255569331642446be05292e3e1f8a51218827168cdclaireho 24265569331642446be05292e3e1f8a51218827168cdclaireho 24275569331642446be05292e3e1f8a51218827168cdclaireho if ( lat->ComponentRecord ) 24285569331642446be05292e3e1f8a51218827168cdclaireho { 24295569331642446be05292e3e1f8a51218827168cdclaireho count = lat->ComponentCount; 24305569331642446be05292e3e1f8a51218827168cdclaireho cr = lat->ComponentRecord; 24315569331642446be05292e3e1f8a51218827168cdclaireho 24325569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < count; m++ ) 24335569331642446be05292e3e1f8a51218827168cdclaireho { 24345569331642446be05292e3e1f8a51218827168cdclaireho lan = cr[m].LigatureAnchor; 24355569331642446be05292e3e1f8a51218827168cdclaireho 24365569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < num_classes; n++ ) 24375569331642446be05292e3e1f8a51218827168cdclaireho Free_Anchor( &lan[n] ); 24385569331642446be05292e3e1f8a51218827168cdclaireho 24395569331642446be05292e3e1f8a51218827168cdclaireho FREE( lan ); 24405569331642446be05292e3e1f8a51218827168cdclaireho } 24415569331642446be05292e3e1f8a51218827168cdclaireho 24425569331642446be05292e3e1f8a51218827168cdclaireho FREE( cr ); 24435569331642446be05292e3e1f8a51218827168cdclaireho } 24445569331642446be05292e3e1f8a51218827168cdclaireho} 24455569331642446be05292e3e1f8a51218827168cdclaireho 24465569331642446be05292e3e1f8a51218827168cdclaireho 24475569331642446be05292e3e1f8a51218827168cdclaireho/* LigatureArray */ 24485569331642446be05292e3e1f8a51218827168cdclaireho 24495569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_LigatureArray( HB_LigatureArray* la, 24505569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort num_classes, 24515569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 24525569331642446be05292e3e1f8a51218827168cdclaireho{ 24535569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 24545569331642446be05292e3e1f8a51218827168cdclaireho 24555569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, m, count; 24565569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 24575569331642446be05292e3e1f8a51218827168cdclaireho 24585569331642446be05292e3e1f8a51218827168cdclaireho HB_LigatureAttach* lat; 24595569331642446be05292e3e1f8a51218827168cdclaireho 24605569331642446be05292e3e1f8a51218827168cdclaireho 24615569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 24625569331642446be05292e3e1f8a51218827168cdclaireho 24635569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 24645569331642446be05292e3e1f8a51218827168cdclaireho return error; 24655569331642446be05292e3e1f8a51218827168cdclaireho 24665569331642446be05292e3e1f8a51218827168cdclaireho count = la->LigatureCount = GET_UShort(); 24675569331642446be05292e3e1f8a51218827168cdclaireho 24685569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 24695569331642446be05292e3e1f8a51218827168cdclaireho 24705569331642446be05292e3e1f8a51218827168cdclaireho la->LigatureAttach = NULL; 24715569331642446be05292e3e1f8a51218827168cdclaireho 24725569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( la->LigatureAttach, count, HB_LigatureAttach ) ) 24735569331642446be05292e3e1f8a51218827168cdclaireho return error; 24745569331642446be05292e3e1f8a51218827168cdclaireho 24755569331642446be05292e3e1f8a51218827168cdclaireho lat = la->LigatureAttach; 24765569331642446be05292e3e1f8a51218827168cdclaireho 24775569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 24785569331642446be05292e3e1f8a51218827168cdclaireho { 24795569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 24805569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 24815569331642446be05292e3e1f8a51218827168cdclaireho 24825569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 24835569331642446be05292e3e1f8a51218827168cdclaireho 24845569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 24855569331642446be05292e3e1f8a51218827168cdclaireho 24865569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 24875569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 24885569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_LigatureAttach( &lat[n], num_classes, 24895569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 24905569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 24915569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 24925569331642446be05292e3e1f8a51218827168cdclaireho } 24935569331642446be05292e3e1f8a51218827168cdclaireho 24945569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 24955569331642446be05292e3e1f8a51218827168cdclaireho 24965569331642446be05292e3e1f8a51218827168cdclairehoFail: 24975569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; m++ ) 24985569331642446be05292e3e1f8a51218827168cdclaireho Free_LigatureAttach( &lat[m], num_classes ); 24995569331642446be05292e3e1f8a51218827168cdclaireho 25005569331642446be05292e3e1f8a51218827168cdclaireho FREE( lat ); 25015569331642446be05292e3e1f8a51218827168cdclaireho return error; 25025569331642446be05292e3e1f8a51218827168cdclaireho} 25035569331642446be05292e3e1f8a51218827168cdclaireho 25045569331642446be05292e3e1f8a51218827168cdclaireho 25055569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_LigatureArray( HB_LigatureArray* la, 25065569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort num_classes ) 25075569331642446be05292e3e1f8a51218827168cdclaireho{ 25085569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 25095569331642446be05292e3e1f8a51218827168cdclaireho 25105569331642446be05292e3e1f8a51218827168cdclaireho HB_LigatureAttach* lat; 25115569331642446be05292e3e1f8a51218827168cdclaireho 25125569331642446be05292e3e1f8a51218827168cdclaireho 25135569331642446be05292e3e1f8a51218827168cdclaireho if ( la->LigatureAttach ) 25145569331642446be05292e3e1f8a51218827168cdclaireho { 25155569331642446be05292e3e1f8a51218827168cdclaireho count = la->LigatureCount; 25165569331642446be05292e3e1f8a51218827168cdclaireho lat = la->LigatureAttach; 25175569331642446be05292e3e1f8a51218827168cdclaireho 25185569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 25195569331642446be05292e3e1f8a51218827168cdclaireho Free_LigatureAttach( &lat[n], num_classes ); 25205569331642446be05292e3e1f8a51218827168cdclaireho 25215569331642446be05292e3e1f8a51218827168cdclaireho FREE( lat ); 25225569331642446be05292e3e1f8a51218827168cdclaireho } 25235569331642446be05292e3e1f8a51218827168cdclaireho} 25245569331642446be05292e3e1f8a51218827168cdclaireho 25255569331642446be05292e3e1f8a51218827168cdclaireho 25265569331642446be05292e3e1f8a51218827168cdclaireho/* MarkLigPosFormat1 */ 25275569331642446be05292e3e1f8a51218827168cdclaireho 25285569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_MarkLigPos( HB_GPOS_SubTable* st, 25295569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 25305569331642446be05292e3e1f8a51218827168cdclaireho{ 25315569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 25325569331642446be05292e3e1f8a51218827168cdclaireho HB_MarkLigPos* mlp = &st->marklig; 25335569331642446be05292e3e1f8a51218827168cdclaireho 25345569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 25355569331642446be05292e3e1f8a51218827168cdclaireho 25365569331642446be05292e3e1f8a51218827168cdclaireho 25375569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 25385569331642446be05292e3e1f8a51218827168cdclaireho 25395569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 4L ) ) 25405569331642446be05292e3e1f8a51218827168cdclaireho return error; 25415569331642446be05292e3e1f8a51218827168cdclaireho 25425569331642446be05292e3e1f8a51218827168cdclaireho mlp->PosFormat = GET_UShort(); 25435569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 25445569331642446be05292e3e1f8a51218827168cdclaireho 25455569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 25465569331642446be05292e3e1f8a51218827168cdclaireho 25475569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 25485569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 25495569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &mlp->MarkCoverage, stream ) ) != HB_Err_Ok ) 25505569331642446be05292e3e1f8a51218827168cdclaireho return error; 25515569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 25525569331642446be05292e3e1f8a51218827168cdclaireho 25535569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 25545569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 25555569331642446be05292e3e1f8a51218827168cdclaireho 25565569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 25575569331642446be05292e3e1f8a51218827168cdclaireho 25585569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 25595569331642446be05292e3e1f8a51218827168cdclaireho 25605569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 25615569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 25625569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &mlp->LigatureCoverage, 25635569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 25645569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 25655569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 25665569331642446be05292e3e1f8a51218827168cdclaireho 25675569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 4L ) ) 25685569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 25695569331642446be05292e3e1f8a51218827168cdclaireho 25705569331642446be05292e3e1f8a51218827168cdclaireho mlp->ClassCount = GET_UShort(); 25715569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 25725569331642446be05292e3e1f8a51218827168cdclaireho 25735569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 25745569331642446be05292e3e1f8a51218827168cdclaireho 25755569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 25765569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 25775569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_MarkArray( &mlp->MarkArray, stream ) ) != HB_Err_Ok ) 25785569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 25795569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 25805569331642446be05292e3e1f8a51218827168cdclaireho 25815569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 25825569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 25835569331642446be05292e3e1f8a51218827168cdclaireho 25845569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 25855569331642446be05292e3e1f8a51218827168cdclaireho 25865569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 25875569331642446be05292e3e1f8a51218827168cdclaireho 25885569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 25895569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 25905569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_LigatureArray( &mlp->LigatureArray, mlp->ClassCount, 25915569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 25925569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 25935569331642446be05292e3e1f8a51218827168cdclaireho 25945569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 25955569331642446be05292e3e1f8a51218827168cdclaireho 25965569331642446be05292e3e1f8a51218827168cdclairehoFail1: 25975569331642446be05292e3e1f8a51218827168cdclaireho Free_MarkArray( &mlp->MarkArray ); 25985569331642446be05292e3e1f8a51218827168cdclaireho 25995569331642446be05292e3e1f8a51218827168cdclairehoFail2: 26005569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &mlp->LigatureCoverage ); 26015569331642446be05292e3e1f8a51218827168cdclaireho 26025569331642446be05292e3e1f8a51218827168cdclairehoFail3: 26035569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &mlp->MarkCoverage ); 26045569331642446be05292e3e1f8a51218827168cdclaireho return error; 26055569331642446be05292e3e1f8a51218827168cdclaireho} 26065569331642446be05292e3e1f8a51218827168cdclaireho 26075569331642446be05292e3e1f8a51218827168cdclaireho 26085569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_MarkLigPos( HB_GPOS_SubTable* st) 26095569331642446be05292e3e1f8a51218827168cdclaireho{ 26105569331642446be05292e3e1f8a51218827168cdclaireho HB_MarkLigPos* mlp = &st->marklig; 26115569331642446be05292e3e1f8a51218827168cdclaireho 26125569331642446be05292e3e1f8a51218827168cdclaireho Free_LigatureArray( &mlp->LigatureArray, mlp->ClassCount ); 26135569331642446be05292e3e1f8a51218827168cdclaireho Free_MarkArray( &mlp->MarkArray ); 26145569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &mlp->LigatureCoverage ); 26155569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &mlp->MarkCoverage ); 26165569331642446be05292e3e1f8a51218827168cdclaireho} 26175569331642446be05292e3e1f8a51218827168cdclaireho 26185569331642446be05292e3e1f8a51218827168cdclaireho 26195569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Lookup_MarkLigPos( GPOS_Instance* gpi, 26205569331642446be05292e3e1f8a51218827168cdclaireho HB_GPOS_SubTable* st, 26215569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 26225569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort flags, 26235569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 26245569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 26255569331642446be05292e3e1f8a51218827168cdclaireho{ 26265569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort i, j, mark_index, lig_index, property, class; 26275569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort mark_glyph; 26285569331642446be05292e3e1f8a51218827168cdclaireho HB_Fixed x_mark_value, y_mark_value, x_lig_value, y_lig_value; 26295569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 26305569331642446be05292e3e1f8a51218827168cdclaireho HB_GPOSHeader* gpos = gpi->gpos; 26315569331642446be05292e3e1f8a51218827168cdclaireho HB_MarkLigPos* mlp = &st->marklig; 26325569331642446be05292e3e1f8a51218827168cdclaireho 26335569331642446be05292e3e1f8a51218827168cdclaireho HB_MarkArray* ma; 26345569331642446be05292e3e1f8a51218827168cdclaireho HB_LigatureArray* la; 26355569331642446be05292e3e1f8a51218827168cdclaireho HB_LigatureAttach* lat; 26365569331642446be05292e3e1f8a51218827168cdclaireho HB_ComponentRecord* cr; 26375569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort comp_index; 26385569331642446be05292e3e1f8a51218827168cdclaireho HB_Anchor* mark_anchor; 26395569331642446be05292e3e1f8a51218827168cdclaireho HB_Anchor* lig_anchor; 26405569331642446be05292e3e1f8a51218827168cdclaireho 26415569331642446be05292e3e1f8a51218827168cdclaireho HB_Position o; 26425569331642446be05292e3e1f8a51218827168cdclaireho 26435569331642446be05292e3e1f8a51218827168cdclaireho HB_UNUSED(nesting_level); 26445569331642446be05292e3e1f8a51218827168cdclaireho 26455569331642446be05292e3e1f8a51218827168cdclaireho if ( context_length != 0xFFFF && context_length < 1 ) 26465569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 26475569331642446be05292e3e1f8a51218827168cdclaireho 26485569331642446be05292e3e1f8a51218827168cdclaireho if ( flags & HB_LOOKUP_FLAG_IGNORE_LIGATURES ) 26495569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 26505569331642446be05292e3e1f8a51218827168cdclaireho 26515569331642446be05292e3e1f8a51218827168cdclaireho mark_glyph = IN_CURGLYPH(); 26525569331642446be05292e3e1f8a51218827168cdclaireho 26535569331642446be05292e3e1f8a51218827168cdclaireho if ( CHECK_Property( gpos->gdef, IN_CURITEM(), flags, &property ) ) 26545569331642446be05292e3e1f8a51218827168cdclaireho return error; 26555569331642446be05292e3e1f8a51218827168cdclaireho 26565569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &mlp->MarkCoverage, mark_glyph, &mark_index ); 26575569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 26585569331642446be05292e3e1f8a51218827168cdclaireho return error; 26595569331642446be05292e3e1f8a51218827168cdclaireho 26605569331642446be05292e3e1f8a51218827168cdclaireho /* now we search backwards for a non-mark glyph */ 26615569331642446be05292e3e1f8a51218827168cdclaireho 26625569331642446be05292e3e1f8a51218827168cdclaireho i = 1; 26635569331642446be05292e3e1f8a51218827168cdclaireho j = buffer->in_pos - 1; 26645569331642446be05292e3e1f8a51218827168cdclaireho 26655569331642446be05292e3e1f8a51218827168cdclaireho while ( i <= buffer->in_pos ) 26665569331642446be05292e3e1f8a51218827168cdclaireho { 26675569331642446be05292e3e1f8a51218827168cdclaireho error = HB_GDEF_Get_Glyph_Property( gpos->gdef, IN_GLYPH( j ), 26685569331642446be05292e3e1f8a51218827168cdclaireho &property ); 26695569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 26705569331642446be05292e3e1f8a51218827168cdclaireho return error; 26715569331642446be05292e3e1f8a51218827168cdclaireho 26725569331642446be05292e3e1f8a51218827168cdclaireho if ( !( property == HB_GDEF_MARK || property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) ) 26735569331642446be05292e3e1f8a51218827168cdclaireho break; 26745569331642446be05292e3e1f8a51218827168cdclaireho 26755569331642446be05292e3e1f8a51218827168cdclaireho i++; 26765569331642446be05292e3e1f8a51218827168cdclaireho j--; 26775569331642446be05292e3e1f8a51218827168cdclaireho } 26785569331642446be05292e3e1f8a51218827168cdclaireho 26795569331642446be05292e3e1f8a51218827168cdclaireho /* Similar to Lookup_MarkBasePos(), I suspect that this assertion is 26805569331642446be05292e3e1f8a51218827168cdclaireho too strong, thus it is commented out. */ 26815569331642446be05292e3e1f8a51218827168cdclaireho#if 0 26825569331642446be05292e3e1f8a51218827168cdclaireho if ( property != HB_GDEF_LIGATURE ) 26835569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 26845569331642446be05292e3e1f8a51218827168cdclaireho#endif 26855569331642446be05292e3e1f8a51218827168cdclaireho 26865569331642446be05292e3e1f8a51218827168cdclaireho if ( i > buffer->in_pos ) 26875569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 26885569331642446be05292e3e1f8a51218827168cdclaireho 26895569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &mlp->LigatureCoverage, IN_GLYPH( j ), 26905569331642446be05292e3e1f8a51218827168cdclaireho &lig_index ); 26915569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 26925569331642446be05292e3e1f8a51218827168cdclaireho return error; 26935569331642446be05292e3e1f8a51218827168cdclaireho 26945569331642446be05292e3e1f8a51218827168cdclaireho ma = &mlp->MarkArray; 26955569331642446be05292e3e1f8a51218827168cdclaireho 26965569331642446be05292e3e1f8a51218827168cdclaireho if ( mark_index >= ma->MarkCount ) 26975569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable); 26985569331642446be05292e3e1f8a51218827168cdclaireho 26995569331642446be05292e3e1f8a51218827168cdclaireho class = ma->MarkRecord[mark_index].Class; 27005569331642446be05292e3e1f8a51218827168cdclaireho mark_anchor = &ma->MarkRecord[mark_index].MarkAnchor; 27015569331642446be05292e3e1f8a51218827168cdclaireho 27025569331642446be05292e3e1f8a51218827168cdclaireho if ( class >= mlp->ClassCount ) 27035569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable); 27045569331642446be05292e3e1f8a51218827168cdclaireho 27055569331642446be05292e3e1f8a51218827168cdclaireho la = &mlp->LigatureArray; 27065569331642446be05292e3e1f8a51218827168cdclaireho 27075569331642446be05292e3e1f8a51218827168cdclaireho if ( lig_index >= la->LigatureCount ) 27085569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable); 27095569331642446be05292e3e1f8a51218827168cdclaireho 27105569331642446be05292e3e1f8a51218827168cdclaireho lat = &la->LigatureAttach[lig_index]; 27115569331642446be05292e3e1f8a51218827168cdclaireho 27125569331642446be05292e3e1f8a51218827168cdclaireho /* We must now check whether the ligature ID of the current mark glyph 27135569331642446be05292e3e1f8a51218827168cdclaireho is identical to the ligature ID of the found ligature. If yes, we 27145569331642446be05292e3e1f8a51218827168cdclaireho can directly use the component index. If not, we attach the mark 27155569331642446be05292e3e1f8a51218827168cdclaireho glyph to the last component of the ligature. */ 27165569331642446be05292e3e1f8a51218827168cdclaireho 27175569331642446be05292e3e1f8a51218827168cdclaireho if ( IN_LIGID( j ) == IN_LIGID( buffer->in_pos) ) 27185569331642446be05292e3e1f8a51218827168cdclaireho { 27195569331642446be05292e3e1f8a51218827168cdclaireho comp_index = IN_COMPONENT( buffer->in_pos ); 27205569331642446be05292e3e1f8a51218827168cdclaireho if ( comp_index >= lat->ComponentCount ) 27215569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 27225569331642446be05292e3e1f8a51218827168cdclaireho } 27235569331642446be05292e3e1f8a51218827168cdclaireho else 27245569331642446be05292e3e1f8a51218827168cdclaireho comp_index = lat->ComponentCount - 1; 27255569331642446be05292e3e1f8a51218827168cdclaireho 27265569331642446be05292e3e1f8a51218827168cdclaireho cr = &lat->ComponentRecord[comp_index]; 27275569331642446be05292e3e1f8a51218827168cdclaireho lig_anchor = &cr->LigatureAnchor[class]; 27285569331642446be05292e3e1f8a51218827168cdclaireho 27295569331642446be05292e3e1f8a51218827168cdclaireho error = Get_Anchor( gpi, mark_anchor, IN_CURGLYPH(), 27305569331642446be05292e3e1f8a51218827168cdclaireho &x_mark_value, &y_mark_value ); 27315569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 27325569331642446be05292e3e1f8a51218827168cdclaireho return error; 27335569331642446be05292e3e1f8a51218827168cdclaireho error = Get_Anchor( gpi, lig_anchor, IN_GLYPH( j ), 27345569331642446be05292e3e1f8a51218827168cdclaireho &x_lig_value, &y_lig_value ); 27355569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 27365569331642446be05292e3e1f8a51218827168cdclaireho return error; 27375569331642446be05292e3e1f8a51218827168cdclaireho 27385569331642446be05292e3e1f8a51218827168cdclaireho /* anchor points are not cumulative */ 27395569331642446be05292e3e1f8a51218827168cdclaireho 27405569331642446be05292e3e1f8a51218827168cdclaireho o = POSITION( buffer->in_pos ); 27415569331642446be05292e3e1f8a51218827168cdclaireho 27425569331642446be05292e3e1f8a51218827168cdclaireho o->x_pos = x_lig_value - x_mark_value; 27435569331642446be05292e3e1f8a51218827168cdclaireho o->y_pos = y_lig_value - y_mark_value; 27445569331642446be05292e3e1f8a51218827168cdclaireho o->x_advance = 0; 27455569331642446be05292e3e1f8a51218827168cdclaireho o->y_advance = 0; 27465569331642446be05292e3e1f8a51218827168cdclaireho o->back = i; 27475569331642446be05292e3e1f8a51218827168cdclaireho 27485569331642446be05292e3e1f8a51218827168cdclaireho (buffer->in_pos)++; 27495569331642446be05292e3e1f8a51218827168cdclaireho 27505569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 27515569331642446be05292e3e1f8a51218827168cdclaireho} 27525569331642446be05292e3e1f8a51218827168cdclaireho 27535569331642446be05292e3e1f8a51218827168cdclaireho 27545569331642446be05292e3e1f8a51218827168cdclaireho/* LookupType 6 */ 27555569331642446be05292e3e1f8a51218827168cdclaireho 27565569331642446be05292e3e1f8a51218827168cdclaireho/* Mark2Array */ 27575569331642446be05292e3e1f8a51218827168cdclaireho 27585569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_Mark2Array( HB_Mark2Array* m2a, 27595569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort num_classes, 27605569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 27615569331642446be05292e3e1f8a51218827168cdclaireho{ 27625569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 27635569331642446be05292e3e1f8a51218827168cdclaireho 27645569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort m, n, count; 27655569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 27665569331642446be05292e3e1f8a51218827168cdclaireho 27675569331642446be05292e3e1f8a51218827168cdclaireho HB_Mark2Record *m2r; 27685569331642446be05292e3e1f8a51218827168cdclaireho HB_Anchor *m2an, *m2ans; 27695569331642446be05292e3e1f8a51218827168cdclaireho 27705569331642446be05292e3e1f8a51218827168cdclaireho 27715569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 27725569331642446be05292e3e1f8a51218827168cdclaireho 27735569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 27745569331642446be05292e3e1f8a51218827168cdclaireho return error; 27755569331642446be05292e3e1f8a51218827168cdclaireho 27765569331642446be05292e3e1f8a51218827168cdclaireho count = m2a->Mark2Count = GET_UShort(); 27775569331642446be05292e3e1f8a51218827168cdclaireho 27785569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 27795569331642446be05292e3e1f8a51218827168cdclaireho 27805569331642446be05292e3e1f8a51218827168cdclaireho m2a->Mark2Record = NULL; 27815569331642446be05292e3e1f8a51218827168cdclaireho 27825569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( m2a->Mark2Record, count, HB_Mark2Record ) ) 27835569331642446be05292e3e1f8a51218827168cdclaireho return error; 27845569331642446be05292e3e1f8a51218827168cdclaireho 27855569331642446be05292e3e1f8a51218827168cdclaireho m2r = m2a->Mark2Record; 27865569331642446be05292e3e1f8a51218827168cdclaireho 27875569331642446be05292e3e1f8a51218827168cdclaireho m2ans = NULL; 27885569331642446be05292e3e1f8a51218827168cdclaireho 27895569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( m2ans, count * num_classes, HB_Anchor ) ) 27905569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 27915569331642446be05292e3e1f8a51218827168cdclaireho 27925569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < count; m++ ) 27935569331642446be05292e3e1f8a51218827168cdclaireho { 27945569331642446be05292e3e1f8a51218827168cdclaireho m2an = m2r[m].Mark2Anchor = m2ans + m * num_classes; 27955569331642446be05292e3e1f8a51218827168cdclaireho 27965569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < num_classes; n++ ) 27975569331642446be05292e3e1f8a51218827168cdclaireho { 27985569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 27995569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 28005569331642446be05292e3e1f8a51218827168cdclaireho 28015569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 28025569331642446be05292e3e1f8a51218827168cdclaireho 28035569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 28045569331642446be05292e3e1f8a51218827168cdclaireho 28055569331642446be05292e3e1f8a51218827168cdclaireho if (new_offset == base_offset) { 28065569331642446be05292e3e1f8a51218827168cdclaireho /* Anchor table not provided. Skip loading. 28075569331642446be05292e3e1f8a51218827168cdclaireho * Some versions of FreeSans hit this. */ 28085569331642446be05292e3e1f8a51218827168cdclaireho m2an[n].PosFormat = 0; 28095569331642446be05292e3e1f8a51218827168cdclaireho continue; 28105569331642446be05292e3e1f8a51218827168cdclaireho } 28115569331642446be05292e3e1f8a51218827168cdclaireho 28125569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 28135569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 28145569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_Anchor( &m2an[n], stream ) ) != HB_Err_Ok ) 28155569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 28165569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 28175569331642446be05292e3e1f8a51218827168cdclaireho } 28185569331642446be05292e3e1f8a51218827168cdclaireho } 28195569331642446be05292e3e1f8a51218827168cdclaireho 28205569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 28215569331642446be05292e3e1f8a51218827168cdclaireho 28225569331642446be05292e3e1f8a51218827168cdclairehoFail: 28235569331642446be05292e3e1f8a51218827168cdclaireho FREE( m2ans ); 28245569331642446be05292e3e1f8a51218827168cdclaireho FREE( m2r ); 28255569331642446be05292e3e1f8a51218827168cdclaireho return error; 28265569331642446be05292e3e1f8a51218827168cdclaireho} 28275569331642446be05292e3e1f8a51218827168cdclaireho 28285569331642446be05292e3e1f8a51218827168cdclaireho 28295569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_Mark2Array( HB_Mark2Array* m2a, 28305569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort num_classes ) 28315569331642446be05292e3e1f8a51218827168cdclaireho{ 28325569331642446be05292e3e1f8a51218827168cdclaireho HB_Mark2Record *m2r; 28335569331642446be05292e3e1f8a51218827168cdclaireho HB_Anchor *m2ans; 28345569331642446be05292e3e1f8a51218827168cdclaireho 28355569331642446be05292e3e1f8a51218827168cdclaireho HB_UNUSED(num_classes); 28365569331642446be05292e3e1f8a51218827168cdclaireho 28375569331642446be05292e3e1f8a51218827168cdclaireho if ( m2a->Mark2Record ) 28385569331642446be05292e3e1f8a51218827168cdclaireho { 28395569331642446be05292e3e1f8a51218827168cdclaireho m2r = m2a->Mark2Record; 28405569331642446be05292e3e1f8a51218827168cdclaireho 28415569331642446be05292e3e1f8a51218827168cdclaireho if ( m2a->Mark2Count ) 28425569331642446be05292e3e1f8a51218827168cdclaireho { 28435569331642446be05292e3e1f8a51218827168cdclaireho m2ans = m2r[0].Mark2Anchor; 28445569331642446be05292e3e1f8a51218827168cdclaireho FREE( m2ans ); 28455569331642446be05292e3e1f8a51218827168cdclaireho } 28465569331642446be05292e3e1f8a51218827168cdclaireho 28475569331642446be05292e3e1f8a51218827168cdclaireho FREE( m2r ); 28485569331642446be05292e3e1f8a51218827168cdclaireho } 28495569331642446be05292e3e1f8a51218827168cdclaireho} 28505569331642446be05292e3e1f8a51218827168cdclaireho 28515569331642446be05292e3e1f8a51218827168cdclaireho 28525569331642446be05292e3e1f8a51218827168cdclaireho/* MarkMarkPosFormat1 */ 28535569331642446be05292e3e1f8a51218827168cdclaireho 28545569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_MarkMarkPos( HB_GPOS_SubTable* st, 28555569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 28565569331642446be05292e3e1f8a51218827168cdclaireho{ 28575569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 28585569331642446be05292e3e1f8a51218827168cdclaireho HB_MarkMarkPos* mmp = &st->markmark; 28595569331642446be05292e3e1f8a51218827168cdclaireho 28605569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 28615569331642446be05292e3e1f8a51218827168cdclaireho 28625569331642446be05292e3e1f8a51218827168cdclaireho 28635569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 28645569331642446be05292e3e1f8a51218827168cdclaireho 28655569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 4L ) ) 28665569331642446be05292e3e1f8a51218827168cdclaireho return error; 28675569331642446be05292e3e1f8a51218827168cdclaireho 28685569331642446be05292e3e1f8a51218827168cdclaireho mmp->PosFormat = GET_UShort(); 28695569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 28705569331642446be05292e3e1f8a51218827168cdclaireho 28715569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 28725569331642446be05292e3e1f8a51218827168cdclaireho 28735569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 28745569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 28755569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &mmp->Mark1Coverage, 28765569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 28775569331642446be05292e3e1f8a51218827168cdclaireho return error; 28785569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 28795569331642446be05292e3e1f8a51218827168cdclaireho 28805569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 28815569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 28825569331642446be05292e3e1f8a51218827168cdclaireho 28835569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 28845569331642446be05292e3e1f8a51218827168cdclaireho 28855569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 28865569331642446be05292e3e1f8a51218827168cdclaireho 28875569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 28885569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 28895569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &mmp->Mark2Coverage, 28905569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 28915569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 28925569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 28935569331642446be05292e3e1f8a51218827168cdclaireho 28945569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 4L ) ) 28955569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 28965569331642446be05292e3e1f8a51218827168cdclaireho 28975569331642446be05292e3e1f8a51218827168cdclaireho mmp->ClassCount = GET_UShort(); 28985569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 28995569331642446be05292e3e1f8a51218827168cdclaireho 29005569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 29015569331642446be05292e3e1f8a51218827168cdclaireho 29025569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 29035569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 29045569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_MarkArray( &mmp->Mark1Array, stream ) ) != HB_Err_Ok ) 29055569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 29065569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 29075569331642446be05292e3e1f8a51218827168cdclaireho 29085569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 29095569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 29105569331642446be05292e3e1f8a51218827168cdclaireho 29115569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 29125569331642446be05292e3e1f8a51218827168cdclaireho 29135569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 29145569331642446be05292e3e1f8a51218827168cdclaireho 29155569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 29165569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 29175569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_Mark2Array( &mmp->Mark2Array, mmp->ClassCount, 29185569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 29195569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 29205569331642446be05292e3e1f8a51218827168cdclaireho 29215569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 29225569331642446be05292e3e1f8a51218827168cdclaireho 29235569331642446be05292e3e1f8a51218827168cdclairehoFail1: 29245569331642446be05292e3e1f8a51218827168cdclaireho Free_MarkArray( &mmp->Mark1Array ); 29255569331642446be05292e3e1f8a51218827168cdclaireho 29265569331642446be05292e3e1f8a51218827168cdclairehoFail2: 29275569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &mmp->Mark2Coverage ); 29285569331642446be05292e3e1f8a51218827168cdclaireho 29295569331642446be05292e3e1f8a51218827168cdclairehoFail3: 29305569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &mmp->Mark1Coverage ); 29315569331642446be05292e3e1f8a51218827168cdclaireho return error; 29325569331642446be05292e3e1f8a51218827168cdclaireho} 29335569331642446be05292e3e1f8a51218827168cdclaireho 29345569331642446be05292e3e1f8a51218827168cdclaireho 29355569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_MarkMarkPos( HB_GPOS_SubTable* st) 29365569331642446be05292e3e1f8a51218827168cdclaireho{ 29375569331642446be05292e3e1f8a51218827168cdclaireho HB_MarkMarkPos* mmp = &st->markmark; 29385569331642446be05292e3e1f8a51218827168cdclaireho 29395569331642446be05292e3e1f8a51218827168cdclaireho Free_Mark2Array( &mmp->Mark2Array, mmp->ClassCount ); 29405569331642446be05292e3e1f8a51218827168cdclaireho Free_MarkArray( &mmp->Mark1Array ); 29415569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &mmp->Mark2Coverage ); 29425569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &mmp->Mark1Coverage ); 29435569331642446be05292e3e1f8a51218827168cdclaireho} 29445569331642446be05292e3e1f8a51218827168cdclaireho 29455569331642446be05292e3e1f8a51218827168cdclaireho 29465569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Lookup_MarkMarkPos( GPOS_Instance* gpi, 29475569331642446be05292e3e1f8a51218827168cdclaireho HB_GPOS_SubTable* st, 29485569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 29495569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort flags, 29505569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 29515569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 29525569331642446be05292e3e1f8a51218827168cdclaireho{ 29535569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort i, j, mark1_index, mark2_index, property, class; 29545569331642446be05292e3e1f8a51218827168cdclaireho HB_Fixed x_mark1_value, y_mark1_value, 29555569331642446be05292e3e1f8a51218827168cdclaireho x_mark2_value, y_mark2_value; 29565569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 29575569331642446be05292e3e1f8a51218827168cdclaireho HB_GPOSHeader* gpos = gpi->gpos; 29585569331642446be05292e3e1f8a51218827168cdclaireho HB_MarkMarkPos* mmp = &st->markmark; 29595569331642446be05292e3e1f8a51218827168cdclaireho 29605569331642446be05292e3e1f8a51218827168cdclaireho HB_MarkArray* ma1; 29615569331642446be05292e3e1f8a51218827168cdclaireho HB_Mark2Array* ma2; 29625569331642446be05292e3e1f8a51218827168cdclaireho HB_Mark2Record* m2r; 29635569331642446be05292e3e1f8a51218827168cdclaireho HB_Anchor* mark1_anchor; 29645569331642446be05292e3e1f8a51218827168cdclaireho HB_Anchor* mark2_anchor; 29655569331642446be05292e3e1f8a51218827168cdclaireho 29665569331642446be05292e3e1f8a51218827168cdclaireho HB_Position o; 29675569331642446be05292e3e1f8a51218827168cdclaireho 29685569331642446be05292e3e1f8a51218827168cdclaireho HB_UNUSED(nesting_level); 29695569331642446be05292e3e1f8a51218827168cdclaireho 29705569331642446be05292e3e1f8a51218827168cdclaireho if ( context_length != 0xFFFF && context_length < 1 ) 29715569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 29725569331642446be05292e3e1f8a51218827168cdclaireho 29735569331642446be05292e3e1f8a51218827168cdclaireho if ( flags & HB_LOOKUP_FLAG_IGNORE_MARKS ) 29745569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 29755569331642446be05292e3e1f8a51218827168cdclaireho 29765569331642446be05292e3e1f8a51218827168cdclaireho if ( CHECK_Property( gpos->gdef, IN_CURITEM(), 29775569331642446be05292e3e1f8a51218827168cdclaireho flags, &property ) ) 29785569331642446be05292e3e1f8a51218827168cdclaireho return error; 29795569331642446be05292e3e1f8a51218827168cdclaireho 29805569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &mmp->Mark1Coverage, IN_CURGLYPH(), 29815569331642446be05292e3e1f8a51218827168cdclaireho &mark1_index ); 29825569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 29835569331642446be05292e3e1f8a51218827168cdclaireho return error; 29845569331642446be05292e3e1f8a51218827168cdclaireho 29855569331642446be05292e3e1f8a51218827168cdclaireho /* now we search backwards for a suitable mark glyph until a non-mark 29865569331642446be05292e3e1f8a51218827168cdclaireho glyph */ 29875569331642446be05292e3e1f8a51218827168cdclaireho 29885569331642446be05292e3e1f8a51218827168cdclaireho if ( buffer->in_pos == 0 ) 29895569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 29905569331642446be05292e3e1f8a51218827168cdclaireho 29915569331642446be05292e3e1f8a51218827168cdclaireho i = 1; 29925569331642446be05292e3e1f8a51218827168cdclaireho j = buffer->in_pos - 1; 29935569331642446be05292e3e1f8a51218827168cdclaireho while ( i <= buffer->in_pos ) 29945569331642446be05292e3e1f8a51218827168cdclaireho { 29955569331642446be05292e3e1f8a51218827168cdclaireho error = HB_GDEF_Get_Glyph_Property( gpos->gdef, IN_GLYPH( j ), 29965569331642446be05292e3e1f8a51218827168cdclaireho &property ); 29975569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 29985569331642446be05292e3e1f8a51218827168cdclaireho return error; 29995569331642446be05292e3e1f8a51218827168cdclaireho 30005569331642446be05292e3e1f8a51218827168cdclaireho if ( !( property == HB_GDEF_MARK || property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) ) 30015569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 30025569331642446be05292e3e1f8a51218827168cdclaireho 30035569331642446be05292e3e1f8a51218827168cdclaireho if ( flags & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) 30045569331642446be05292e3e1f8a51218827168cdclaireho { 30055569331642446be05292e3e1f8a51218827168cdclaireho if ( property == (flags & 0xFF00) ) 30065569331642446be05292e3e1f8a51218827168cdclaireho break; 30075569331642446be05292e3e1f8a51218827168cdclaireho } 30085569331642446be05292e3e1f8a51218827168cdclaireho else 30095569331642446be05292e3e1f8a51218827168cdclaireho break; 30105569331642446be05292e3e1f8a51218827168cdclaireho 30115569331642446be05292e3e1f8a51218827168cdclaireho i++; 30125569331642446be05292e3e1f8a51218827168cdclaireho j--; 30135569331642446be05292e3e1f8a51218827168cdclaireho } 30145569331642446be05292e3e1f8a51218827168cdclaireho 30155b51d0c851af1852ecc7562790cbbbee156c2c44claireho if ( i > buffer->in_pos ) 30165b51d0c851af1852ecc7562790cbbbee156c2c44claireho return HB_Err_Not_Covered; 30175b51d0c851af1852ecc7562790cbbbee156c2c44claireho 30185569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &mmp->Mark2Coverage, IN_GLYPH( j ), 30195569331642446be05292e3e1f8a51218827168cdclaireho &mark2_index ); 30205569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 30215569331642446be05292e3e1f8a51218827168cdclaireho return error; 30225569331642446be05292e3e1f8a51218827168cdclaireho 30235569331642446be05292e3e1f8a51218827168cdclaireho ma1 = &mmp->Mark1Array; 30245569331642446be05292e3e1f8a51218827168cdclaireho 30255569331642446be05292e3e1f8a51218827168cdclaireho if ( mark1_index >= ma1->MarkCount ) 30265569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable); 30275569331642446be05292e3e1f8a51218827168cdclaireho 30285569331642446be05292e3e1f8a51218827168cdclaireho class = ma1->MarkRecord[mark1_index].Class; 30295569331642446be05292e3e1f8a51218827168cdclaireho mark1_anchor = &ma1->MarkRecord[mark1_index].MarkAnchor; 30305569331642446be05292e3e1f8a51218827168cdclaireho 30315569331642446be05292e3e1f8a51218827168cdclaireho if ( class >= mmp->ClassCount ) 30325569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable); 30335569331642446be05292e3e1f8a51218827168cdclaireho 30345569331642446be05292e3e1f8a51218827168cdclaireho ma2 = &mmp->Mark2Array; 30355569331642446be05292e3e1f8a51218827168cdclaireho 30365569331642446be05292e3e1f8a51218827168cdclaireho if ( mark2_index >= ma2->Mark2Count ) 30375569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable); 30385569331642446be05292e3e1f8a51218827168cdclaireho 30395569331642446be05292e3e1f8a51218827168cdclaireho m2r = &ma2->Mark2Record[mark2_index]; 30405569331642446be05292e3e1f8a51218827168cdclaireho mark2_anchor = &m2r->Mark2Anchor[class]; 30415569331642446be05292e3e1f8a51218827168cdclaireho 30425569331642446be05292e3e1f8a51218827168cdclaireho error = Get_Anchor( gpi, mark1_anchor, IN_CURGLYPH(), 30435569331642446be05292e3e1f8a51218827168cdclaireho &x_mark1_value, &y_mark1_value ); 30445569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 30455569331642446be05292e3e1f8a51218827168cdclaireho return error; 30465569331642446be05292e3e1f8a51218827168cdclaireho error = Get_Anchor( gpi, mark2_anchor, IN_GLYPH( j ), 30475569331642446be05292e3e1f8a51218827168cdclaireho &x_mark2_value, &y_mark2_value ); 30485569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 30495569331642446be05292e3e1f8a51218827168cdclaireho return error; 30505569331642446be05292e3e1f8a51218827168cdclaireho 30515569331642446be05292e3e1f8a51218827168cdclaireho /* anchor points are not cumulative */ 30525569331642446be05292e3e1f8a51218827168cdclaireho 30535569331642446be05292e3e1f8a51218827168cdclaireho o = POSITION( buffer->in_pos ); 30545569331642446be05292e3e1f8a51218827168cdclaireho 30555569331642446be05292e3e1f8a51218827168cdclaireho o->x_pos = x_mark2_value - x_mark1_value; 30565569331642446be05292e3e1f8a51218827168cdclaireho o->y_pos = y_mark2_value - y_mark1_value; 30575569331642446be05292e3e1f8a51218827168cdclaireho o->x_advance = 0; 30585569331642446be05292e3e1f8a51218827168cdclaireho o->y_advance = 0; 30595569331642446be05292e3e1f8a51218827168cdclaireho o->back = 1; 30605569331642446be05292e3e1f8a51218827168cdclaireho 30615569331642446be05292e3e1f8a51218827168cdclaireho (buffer->in_pos)++; 30625569331642446be05292e3e1f8a51218827168cdclaireho 30635569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 30645569331642446be05292e3e1f8a51218827168cdclaireho} 30655569331642446be05292e3e1f8a51218827168cdclaireho 30665569331642446be05292e3e1f8a51218827168cdclaireho 30675569331642446be05292e3e1f8a51218827168cdclaireho/* Do the actual positioning for a context positioning (either format 30685569331642446be05292e3e1f8a51218827168cdclaireho 7 or 8). This is only called after we've determined that the stream 30695569331642446be05292e3e1f8a51218827168cdclaireho matches the subrule. */ 30705569331642446be05292e3e1f8a51218827168cdclaireho 30715569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Do_ContextPos( GPOS_Instance* gpi, 30725569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort GlyphCount, 30735569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort PosCount, 30745569331642446be05292e3e1f8a51218827168cdclaireho HB_PosLookupRecord* pos, 30755569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 30765569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 30775569331642446be05292e3e1f8a51218827168cdclaireho{ 30785569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 30795569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt i, old_pos; 30805569331642446be05292e3e1f8a51218827168cdclaireho 30815569331642446be05292e3e1f8a51218827168cdclaireho 30825569331642446be05292e3e1f8a51218827168cdclaireho i = 0; 30835569331642446be05292e3e1f8a51218827168cdclaireho 30845569331642446be05292e3e1f8a51218827168cdclaireho while ( i < GlyphCount ) 30855569331642446be05292e3e1f8a51218827168cdclaireho { 30865569331642446be05292e3e1f8a51218827168cdclaireho if ( PosCount && i == pos->SequenceIndex ) 30875569331642446be05292e3e1f8a51218827168cdclaireho { 30885569331642446be05292e3e1f8a51218827168cdclaireho old_pos = buffer->in_pos; 30895569331642446be05292e3e1f8a51218827168cdclaireho 30905569331642446be05292e3e1f8a51218827168cdclaireho /* Do a positioning */ 30915569331642446be05292e3e1f8a51218827168cdclaireho 30925569331642446be05292e3e1f8a51218827168cdclaireho error = GPOS_Do_Glyph_Lookup( gpi, pos->LookupListIndex, buffer, 30935569331642446be05292e3e1f8a51218827168cdclaireho GlyphCount, nesting_level ); 30945569331642446be05292e3e1f8a51218827168cdclaireho 30955569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 30965569331642446be05292e3e1f8a51218827168cdclaireho return error; 30975569331642446be05292e3e1f8a51218827168cdclaireho 30985569331642446be05292e3e1f8a51218827168cdclaireho pos++; 30995569331642446be05292e3e1f8a51218827168cdclaireho PosCount--; 31005569331642446be05292e3e1f8a51218827168cdclaireho i += buffer->in_pos - old_pos; 31015569331642446be05292e3e1f8a51218827168cdclaireho } 31025569331642446be05292e3e1f8a51218827168cdclaireho else 31035569331642446be05292e3e1f8a51218827168cdclaireho { 31045569331642446be05292e3e1f8a51218827168cdclaireho i++; 31055569331642446be05292e3e1f8a51218827168cdclaireho (buffer->in_pos)++; 31065569331642446be05292e3e1f8a51218827168cdclaireho } 31075569331642446be05292e3e1f8a51218827168cdclaireho } 31085569331642446be05292e3e1f8a51218827168cdclaireho 31095569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 31105569331642446be05292e3e1f8a51218827168cdclaireho} 31115569331642446be05292e3e1f8a51218827168cdclaireho 31125569331642446be05292e3e1f8a51218827168cdclaireho 31135569331642446be05292e3e1f8a51218827168cdclaireho/* LookupType 7 */ 31145569331642446be05292e3e1f8a51218827168cdclaireho 31155569331642446be05292e3e1f8a51218827168cdclaireho/* PosRule */ 31165569331642446be05292e3e1f8a51218827168cdclaireho 31175569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_PosRule( HB_PosRule* pr, 31185569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 31195569331642446be05292e3e1f8a51218827168cdclaireho{ 31205569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 31215569331642446be05292e3e1f8a51218827168cdclaireho 31225569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 31235569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* i; 31245569331642446be05292e3e1f8a51218827168cdclaireho 31255569331642446be05292e3e1f8a51218827168cdclaireho HB_PosLookupRecord* plr; 31265569331642446be05292e3e1f8a51218827168cdclaireho 31275569331642446be05292e3e1f8a51218827168cdclaireho 31285569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 4L ) ) 31295569331642446be05292e3e1f8a51218827168cdclaireho return error; 31305569331642446be05292e3e1f8a51218827168cdclaireho 31315569331642446be05292e3e1f8a51218827168cdclaireho pr->GlyphCount = GET_UShort(); 31325569331642446be05292e3e1f8a51218827168cdclaireho pr->PosCount = GET_UShort(); 31335569331642446be05292e3e1f8a51218827168cdclaireho 31345569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 31355569331642446be05292e3e1f8a51218827168cdclaireho 31365569331642446be05292e3e1f8a51218827168cdclaireho pr->Input = NULL; 31375569331642446be05292e3e1f8a51218827168cdclaireho 31385569331642446be05292e3e1f8a51218827168cdclaireho count = pr->GlyphCount - 1; /* only GlyphCount - 1 elements */ 31395569331642446be05292e3e1f8a51218827168cdclaireho 31405569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( pr->Input, count, HB_UShort ) ) 31415569331642446be05292e3e1f8a51218827168cdclaireho return error; 31425569331642446be05292e3e1f8a51218827168cdclaireho 31435569331642446be05292e3e1f8a51218827168cdclaireho i = pr->Input; 31445569331642446be05292e3e1f8a51218827168cdclaireho 31455569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 2L ) ) 31465569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 31475569331642446be05292e3e1f8a51218827168cdclaireho 31485569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 31495569331642446be05292e3e1f8a51218827168cdclaireho i[n] = GET_UShort(); 31505569331642446be05292e3e1f8a51218827168cdclaireho 31515569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 31525569331642446be05292e3e1f8a51218827168cdclaireho 31535569331642446be05292e3e1f8a51218827168cdclaireho pr->PosLookupRecord = NULL; 31545569331642446be05292e3e1f8a51218827168cdclaireho 31555569331642446be05292e3e1f8a51218827168cdclaireho count = pr->PosCount; 31565569331642446be05292e3e1f8a51218827168cdclaireho 31575569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( pr->PosLookupRecord, count, HB_PosLookupRecord ) ) 31585569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 31595569331642446be05292e3e1f8a51218827168cdclaireho 31605569331642446be05292e3e1f8a51218827168cdclaireho plr = pr->PosLookupRecord; 31615569331642446be05292e3e1f8a51218827168cdclaireho 31625569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 4L ) ) 31635569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 31645569331642446be05292e3e1f8a51218827168cdclaireho 31655569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 31665569331642446be05292e3e1f8a51218827168cdclaireho { 31675569331642446be05292e3e1f8a51218827168cdclaireho plr[n].SequenceIndex = GET_UShort(); 31685569331642446be05292e3e1f8a51218827168cdclaireho plr[n].LookupListIndex = GET_UShort(); 31695569331642446be05292e3e1f8a51218827168cdclaireho } 31705569331642446be05292e3e1f8a51218827168cdclaireho 31715569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 31725569331642446be05292e3e1f8a51218827168cdclaireho 31735569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 31745569331642446be05292e3e1f8a51218827168cdclaireho 31755569331642446be05292e3e1f8a51218827168cdclairehoFail1: 31765569331642446be05292e3e1f8a51218827168cdclaireho FREE( plr ); 31775569331642446be05292e3e1f8a51218827168cdclaireho 31785569331642446be05292e3e1f8a51218827168cdclairehoFail2: 31795569331642446be05292e3e1f8a51218827168cdclaireho FREE( i ); 31805569331642446be05292e3e1f8a51218827168cdclaireho return error; 31815569331642446be05292e3e1f8a51218827168cdclaireho} 31825569331642446be05292e3e1f8a51218827168cdclaireho 31835569331642446be05292e3e1f8a51218827168cdclaireho 31845569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_PosRule( HB_PosRule* pr ) 31855569331642446be05292e3e1f8a51218827168cdclaireho{ 31865569331642446be05292e3e1f8a51218827168cdclaireho FREE( pr->PosLookupRecord ); 31875569331642446be05292e3e1f8a51218827168cdclaireho FREE( pr->Input ); 31885569331642446be05292e3e1f8a51218827168cdclaireho} 31895569331642446be05292e3e1f8a51218827168cdclaireho 31905569331642446be05292e3e1f8a51218827168cdclaireho 31915569331642446be05292e3e1f8a51218827168cdclaireho/* PosRuleSet */ 31925569331642446be05292e3e1f8a51218827168cdclaireho 31935569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_PosRuleSet( HB_PosRuleSet* prs, 31945569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 31955569331642446be05292e3e1f8a51218827168cdclaireho{ 31965569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 31975569331642446be05292e3e1f8a51218827168cdclaireho 31985569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, m, count; 31995569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 32005569331642446be05292e3e1f8a51218827168cdclaireho 32015569331642446be05292e3e1f8a51218827168cdclaireho HB_PosRule* pr; 32025569331642446be05292e3e1f8a51218827168cdclaireho 32035569331642446be05292e3e1f8a51218827168cdclaireho 32045569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 32055569331642446be05292e3e1f8a51218827168cdclaireho 32065569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 32075569331642446be05292e3e1f8a51218827168cdclaireho return error; 32085569331642446be05292e3e1f8a51218827168cdclaireho 32095569331642446be05292e3e1f8a51218827168cdclaireho count = prs->PosRuleCount = GET_UShort(); 32105569331642446be05292e3e1f8a51218827168cdclaireho 32115569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 32125569331642446be05292e3e1f8a51218827168cdclaireho 32135569331642446be05292e3e1f8a51218827168cdclaireho prs->PosRule = NULL; 32145569331642446be05292e3e1f8a51218827168cdclaireho 32155569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( prs->PosRule, count, HB_PosRule ) ) 32165569331642446be05292e3e1f8a51218827168cdclaireho return error; 32175569331642446be05292e3e1f8a51218827168cdclaireho 32185569331642446be05292e3e1f8a51218827168cdclaireho pr = prs->PosRule; 32195569331642446be05292e3e1f8a51218827168cdclaireho 32205569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 32215569331642446be05292e3e1f8a51218827168cdclaireho { 32225569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 32235569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 32245569331642446be05292e3e1f8a51218827168cdclaireho 32255569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 32265569331642446be05292e3e1f8a51218827168cdclaireho 32275569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 32285569331642446be05292e3e1f8a51218827168cdclaireho 32295569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 32305569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 32315569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_PosRule( &pr[n], stream ) ) != HB_Err_Ok ) 32325569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 32335569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 32345569331642446be05292e3e1f8a51218827168cdclaireho } 32355569331642446be05292e3e1f8a51218827168cdclaireho 32365569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 32375569331642446be05292e3e1f8a51218827168cdclaireho 32385569331642446be05292e3e1f8a51218827168cdclairehoFail: 32395569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; m++ ) 32405569331642446be05292e3e1f8a51218827168cdclaireho Free_PosRule( &pr[m] ); 32415569331642446be05292e3e1f8a51218827168cdclaireho 32425569331642446be05292e3e1f8a51218827168cdclaireho FREE( pr ); 32435569331642446be05292e3e1f8a51218827168cdclaireho return error; 32445569331642446be05292e3e1f8a51218827168cdclaireho} 32455569331642446be05292e3e1f8a51218827168cdclaireho 32465569331642446be05292e3e1f8a51218827168cdclaireho 32475569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_PosRuleSet( HB_PosRuleSet* prs ) 32485569331642446be05292e3e1f8a51218827168cdclaireho{ 32495569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 32505569331642446be05292e3e1f8a51218827168cdclaireho 32515569331642446be05292e3e1f8a51218827168cdclaireho HB_PosRule* pr; 32525569331642446be05292e3e1f8a51218827168cdclaireho 32535569331642446be05292e3e1f8a51218827168cdclaireho 32545569331642446be05292e3e1f8a51218827168cdclaireho if ( prs->PosRule ) 32555569331642446be05292e3e1f8a51218827168cdclaireho { 32565569331642446be05292e3e1f8a51218827168cdclaireho count = prs->PosRuleCount; 32575569331642446be05292e3e1f8a51218827168cdclaireho pr = prs->PosRule; 32585569331642446be05292e3e1f8a51218827168cdclaireho 32595569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 32605569331642446be05292e3e1f8a51218827168cdclaireho Free_PosRule( &pr[n] ); 32615569331642446be05292e3e1f8a51218827168cdclaireho 32625569331642446be05292e3e1f8a51218827168cdclaireho FREE( pr ); 32635569331642446be05292e3e1f8a51218827168cdclaireho } 32645569331642446be05292e3e1f8a51218827168cdclaireho} 32655569331642446be05292e3e1f8a51218827168cdclaireho 32665569331642446be05292e3e1f8a51218827168cdclaireho 32675569331642446be05292e3e1f8a51218827168cdclaireho/* ContextPosFormat1 */ 32685569331642446be05292e3e1f8a51218827168cdclaireho 32695569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_ContextPos1( HB_ContextPosFormat1* cpf1, 32705569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 32715569331642446be05292e3e1f8a51218827168cdclaireho{ 32725569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 32735569331642446be05292e3e1f8a51218827168cdclaireho 32745569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, m, count; 32755569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 32765569331642446be05292e3e1f8a51218827168cdclaireho 32775569331642446be05292e3e1f8a51218827168cdclaireho HB_PosRuleSet* prs; 32785569331642446be05292e3e1f8a51218827168cdclaireho 32795569331642446be05292e3e1f8a51218827168cdclaireho 32805569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos() - 2L; 32815569331642446be05292e3e1f8a51218827168cdclaireho 32825569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 32835569331642446be05292e3e1f8a51218827168cdclaireho return error; 32845569331642446be05292e3e1f8a51218827168cdclaireho 32855569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 32865569331642446be05292e3e1f8a51218827168cdclaireho 32875569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 32885569331642446be05292e3e1f8a51218827168cdclaireho 32895569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 32905569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 32915569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &cpf1->Coverage, stream ) ) != HB_Err_Ok ) 32925569331642446be05292e3e1f8a51218827168cdclaireho return error; 32935569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 32945569331642446be05292e3e1f8a51218827168cdclaireho 32955569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 32965569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 32975569331642446be05292e3e1f8a51218827168cdclaireho 32985569331642446be05292e3e1f8a51218827168cdclaireho count = cpf1->PosRuleSetCount = GET_UShort(); 32995569331642446be05292e3e1f8a51218827168cdclaireho 33005569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 33015569331642446be05292e3e1f8a51218827168cdclaireho 33025569331642446be05292e3e1f8a51218827168cdclaireho cpf1->PosRuleSet = NULL; 33035569331642446be05292e3e1f8a51218827168cdclaireho 33045569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( cpf1->PosRuleSet, count, HB_PosRuleSet ) ) 33055569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 33065569331642446be05292e3e1f8a51218827168cdclaireho 33075569331642446be05292e3e1f8a51218827168cdclaireho prs = cpf1->PosRuleSet; 33085569331642446be05292e3e1f8a51218827168cdclaireho 33095569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 33105569331642446be05292e3e1f8a51218827168cdclaireho { 33115569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 33125569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 33135569331642446be05292e3e1f8a51218827168cdclaireho 33145569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 33155569331642446be05292e3e1f8a51218827168cdclaireho 33165569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 33175569331642446be05292e3e1f8a51218827168cdclaireho 33185569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 33195569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 33205569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_PosRuleSet( &prs[n], stream ) ) != HB_Err_Ok ) 33215569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 33225569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 33235569331642446be05292e3e1f8a51218827168cdclaireho } 33245569331642446be05292e3e1f8a51218827168cdclaireho 33255569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 33265569331642446be05292e3e1f8a51218827168cdclaireho 33275569331642446be05292e3e1f8a51218827168cdclairehoFail1: 33285569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; m++ ) 33295569331642446be05292e3e1f8a51218827168cdclaireho Free_PosRuleSet( &prs[m] ); 33305569331642446be05292e3e1f8a51218827168cdclaireho 33315569331642446be05292e3e1f8a51218827168cdclaireho FREE( prs ); 33325569331642446be05292e3e1f8a51218827168cdclaireho 33335569331642446be05292e3e1f8a51218827168cdclairehoFail2: 33345569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &cpf1->Coverage ); 33355569331642446be05292e3e1f8a51218827168cdclaireho return error; 33365569331642446be05292e3e1f8a51218827168cdclaireho} 33375569331642446be05292e3e1f8a51218827168cdclaireho 33385569331642446be05292e3e1f8a51218827168cdclaireho 33395569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_ContextPos1( HB_ContextPosFormat1* cpf1 ) 33405569331642446be05292e3e1f8a51218827168cdclaireho{ 33415569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 33425569331642446be05292e3e1f8a51218827168cdclaireho 33435569331642446be05292e3e1f8a51218827168cdclaireho HB_PosRuleSet* prs; 33445569331642446be05292e3e1f8a51218827168cdclaireho 33455569331642446be05292e3e1f8a51218827168cdclaireho 33465569331642446be05292e3e1f8a51218827168cdclaireho if ( cpf1->PosRuleSet ) 33475569331642446be05292e3e1f8a51218827168cdclaireho { 33485569331642446be05292e3e1f8a51218827168cdclaireho count = cpf1->PosRuleSetCount; 33495569331642446be05292e3e1f8a51218827168cdclaireho prs = cpf1->PosRuleSet; 33505569331642446be05292e3e1f8a51218827168cdclaireho 33515569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 33525569331642446be05292e3e1f8a51218827168cdclaireho Free_PosRuleSet( &prs[n] ); 33535569331642446be05292e3e1f8a51218827168cdclaireho 33545569331642446be05292e3e1f8a51218827168cdclaireho FREE( prs ); 33555569331642446be05292e3e1f8a51218827168cdclaireho } 33565569331642446be05292e3e1f8a51218827168cdclaireho 33575569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &cpf1->Coverage ); 33585569331642446be05292e3e1f8a51218827168cdclaireho} 33595569331642446be05292e3e1f8a51218827168cdclaireho 33605569331642446be05292e3e1f8a51218827168cdclaireho 33615569331642446be05292e3e1f8a51218827168cdclaireho/* PosClassRule */ 33625569331642446be05292e3e1f8a51218827168cdclaireho 33635569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_PosClassRule( HB_ContextPosFormat2* cpf2, 33645569331642446be05292e3e1f8a51218827168cdclaireho HB_PosClassRule* pcr, 33655569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 33665569331642446be05292e3e1f8a51218827168cdclaireho{ 33675569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 33685569331642446be05292e3e1f8a51218827168cdclaireho 33695569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 33705569331642446be05292e3e1f8a51218827168cdclaireho 33715569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* c; 33725569331642446be05292e3e1f8a51218827168cdclaireho HB_PosLookupRecord* plr; 33735569331642446be05292e3e1f8a51218827168cdclaireho 33745569331642446be05292e3e1f8a51218827168cdclaireho 33755569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 4L ) ) 33765569331642446be05292e3e1f8a51218827168cdclaireho return error; 33775569331642446be05292e3e1f8a51218827168cdclaireho 33785569331642446be05292e3e1f8a51218827168cdclaireho pcr->GlyphCount = GET_UShort(); 33795569331642446be05292e3e1f8a51218827168cdclaireho pcr->PosCount = GET_UShort(); 33805569331642446be05292e3e1f8a51218827168cdclaireho 33815569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 33825569331642446be05292e3e1f8a51218827168cdclaireho 33835569331642446be05292e3e1f8a51218827168cdclaireho if ( pcr->GlyphCount > cpf2->MaxContextLength ) 33845569331642446be05292e3e1f8a51218827168cdclaireho cpf2->MaxContextLength = pcr->GlyphCount; 33855569331642446be05292e3e1f8a51218827168cdclaireho 33865569331642446be05292e3e1f8a51218827168cdclaireho pcr->Class = NULL; 33875569331642446be05292e3e1f8a51218827168cdclaireho 33885569331642446be05292e3e1f8a51218827168cdclaireho count = pcr->GlyphCount - 1; /* only GlyphCount - 1 elements */ 33895569331642446be05292e3e1f8a51218827168cdclaireho 33905569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( pcr->Class, count, HB_UShort ) ) 33915569331642446be05292e3e1f8a51218827168cdclaireho return error; 33925569331642446be05292e3e1f8a51218827168cdclaireho 33935569331642446be05292e3e1f8a51218827168cdclaireho c = pcr->Class; 33945569331642446be05292e3e1f8a51218827168cdclaireho 33955569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 2L ) ) 33965569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 33975569331642446be05292e3e1f8a51218827168cdclaireho 33985569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 33995569331642446be05292e3e1f8a51218827168cdclaireho c[n] = GET_UShort(); 34005569331642446be05292e3e1f8a51218827168cdclaireho 34015569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 34025569331642446be05292e3e1f8a51218827168cdclaireho 34035569331642446be05292e3e1f8a51218827168cdclaireho pcr->PosLookupRecord = NULL; 34045569331642446be05292e3e1f8a51218827168cdclaireho 34055569331642446be05292e3e1f8a51218827168cdclaireho count = pcr->PosCount; 34065569331642446be05292e3e1f8a51218827168cdclaireho 34075569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( pcr->PosLookupRecord, count, HB_PosLookupRecord ) ) 34085569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 34095569331642446be05292e3e1f8a51218827168cdclaireho 34105569331642446be05292e3e1f8a51218827168cdclaireho plr = pcr->PosLookupRecord; 34115569331642446be05292e3e1f8a51218827168cdclaireho 34125569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 4L ) ) 34135569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 34145569331642446be05292e3e1f8a51218827168cdclaireho 34155569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 34165569331642446be05292e3e1f8a51218827168cdclaireho { 34175569331642446be05292e3e1f8a51218827168cdclaireho plr[n].SequenceIndex = GET_UShort(); 34185569331642446be05292e3e1f8a51218827168cdclaireho plr[n].LookupListIndex = GET_UShort(); 34195569331642446be05292e3e1f8a51218827168cdclaireho } 34205569331642446be05292e3e1f8a51218827168cdclaireho 34215569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 34225569331642446be05292e3e1f8a51218827168cdclaireho 34235569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 34245569331642446be05292e3e1f8a51218827168cdclaireho 34255569331642446be05292e3e1f8a51218827168cdclairehoFail1: 34265569331642446be05292e3e1f8a51218827168cdclaireho FREE( plr ); 34275569331642446be05292e3e1f8a51218827168cdclaireho 34285569331642446be05292e3e1f8a51218827168cdclairehoFail2: 34295569331642446be05292e3e1f8a51218827168cdclaireho FREE( c ); 34305569331642446be05292e3e1f8a51218827168cdclaireho return error; 34315569331642446be05292e3e1f8a51218827168cdclaireho} 34325569331642446be05292e3e1f8a51218827168cdclaireho 34335569331642446be05292e3e1f8a51218827168cdclaireho 34345569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_PosClassRule( HB_PosClassRule* pcr ) 34355569331642446be05292e3e1f8a51218827168cdclaireho{ 34365569331642446be05292e3e1f8a51218827168cdclaireho FREE( pcr->PosLookupRecord ); 34375569331642446be05292e3e1f8a51218827168cdclaireho FREE( pcr->Class ); 34385569331642446be05292e3e1f8a51218827168cdclaireho} 34395569331642446be05292e3e1f8a51218827168cdclaireho 34405569331642446be05292e3e1f8a51218827168cdclaireho 34415569331642446be05292e3e1f8a51218827168cdclaireho/* PosClassSet */ 34425569331642446be05292e3e1f8a51218827168cdclaireho 34435569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_PosClassSet( HB_ContextPosFormat2* cpf2, 34445569331642446be05292e3e1f8a51218827168cdclaireho HB_PosClassSet* pcs, 34455569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 34465569331642446be05292e3e1f8a51218827168cdclaireho{ 34475569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 34485569331642446be05292e3e1f8a51218827168cdclaireho 34495569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, m, count; 34505569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 34515569331642446be05292e3e1f8a51218827168cdclaireho 34525569331642446be05292e3e1f8a51218827168cdclaireho HB_PosClassRule* pcr; 34535569331642446be05292e3e1f8a51218827168cdclaireho 34545569331642446be05292e3e1f8a51218827168cdclaireho 34555569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 34565569331642446be05292e3e1f8a51218827168cdclaireho 34575569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 34585569331642446be05292e3e1f8a51218827168cdclaireho return error; 34595569331642446be05292e3e1f8a51218827168cdclaireho 34605569331642446be05292e3e1f8a51218827168cdclaireho count = pcs->PosClassRuleCount = GET_UShort(); 34615569331642446be05292e3e1f8a51218827168cdclaireho 34625569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 34635569331642446be05292e3e1f8a51218827168cdclaireho 34645569331642446be05292e3e1f8a51218827168cdclaireho pcs->PosClassRule = NULL; 34655569331642446be05292e3e1f8a51218827168cdclaireho 34665569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( pcs->PosClassRule, count, HB_PosClassRule ) ) 34675569331642446be05292e3e1f8a51218827168cdclaireho return error; 34685569331642446be05292e3e1f8a51218827168cdclaireho 34695569331642446be05292e3e1f8a51218827168cdclaireho pcr = pcs->PosClassRule; 34705569331642446be05292e3e1f8a51218827168cdclaireho 34715569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 34725569331642446be05292e3e1f8a51218827168cdclaireho { 34735569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 34745569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 34755569331642446be05292e3e1f8a51218827168cdclaireho 34765569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 34775569331642446be05292e3e1f8a51218827168cdclaireho 34785569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 34795569331642446be05292e3e1f8a51218827168cdclaireho 34805569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 34815569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 34825569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_PosClassRule( cpf2, &pcr[n], 34835569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 34845569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 34855569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 34865569331642446be05292e3e1f8a51218827168cdclaireho } 34875569331642446be05292e3e1f8a51218827168cdclaireho 34885569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 34895569331642446be05292e3e1f8a51218827168cdclaireho 34905569331642446be05292e3e1f8a51218827168cdclairehoFail: 34915569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; m++ ) 34925569331642446be05292e3e1f8a51218827168cdclaireho Free_PosClassRule( &pcr[m] ); 34935569331642446be05292e3e1f8a51218827168cdclaireho 34945569331642446be05292e3e1f8a51218827168cdclaireho FREE( pcr ); 34955569331642446be05292e3e1f8a51218827168cdclaireho return error; 34965569331642446be05292e3e1f8a51218827168cdclaireho} 34975569331642446be05292e3e1f8a51218827168cdclaireho 34985569331642446be05292e3e1f8a51218827168cdclaireho 34995569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_PosClassSet( HB_PosClassSet* pcs ) 35005569331642446be05292e3e1f8a51218827168cdclaireho{ 35015569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 35025569331642446be05292e3e1f8a51218827168cdclaireho 35035569331642446be05292e3e1f8a51218827168cdclaireho HB_PosClassRule* pcr; 35045569331642446be05292e3e1f8a51218827168cdclaireho 35055569331642446be05292e3e1f8a51218827168cdclaireho 35065569331642446be05292e3e1f8a51218827168cdclaireho if ( pcs->PosClassRule ) 35075569331642446be05292e3e1f8a51218827168cdclaireho { 35085569331642446be05292e3e1f8a51218827168cdclaireho count = pcs->PosClassRuleCount; 35095569331642446be05292e3e1f8a51218827168cdclaireho pcr = pcs->PosClassRule; 35105569331642446be05292e3e1f8a51218827168cdclaireho 35115569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 35125569331642446be05292e3e1f8a51218827168cdclaireho Free_PosClassRule( &pcr[n] ); 35135569331642446be05292e3e1f8a51218827168cdclaireho 35145569331642446be05292e3e1f8a51218827168cdclaireho FREE( pcr ); 35155569331642446be05292e3e1f8a51218827168cdclaireho } 35165569331642446be05292e3e1f8a51218827168cdclaireho} 35175569331642446be05292e3e1f8a51218827168cdclaireho 35185569331642446be05292e3e1f8a51218827168cdclaireho 35195569331642446be05292e3e1f8a51218827168cdclaireho/* ContextPosFormat2 */ 35205569331642446be05292e3e1f8a51218827168cdclaireho 35215569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_ContextPos2( HB_ContextPosFormat2* cpf2, 35225569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 35235569331642446be05292e3e1f8a51218827168cdclaireho{ 35245569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 35255569331642446be05292e3e1f8a51218827168cdclaireho 35265569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, m, count; 35275569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 35285569331642446be05292e3e1f8a51218827168cdclaireho 35295569331642446be05292e3e1f8a51218827168cdclaireho HB_PosClassSet* pcs; 35305569331642446be05292e3e1f8a51218827168cdclaireho 35315569331642446be05292e3e1f8a51218827168cdclaireho 35325569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos() - 2; 35335569331642446be05292e3e1f8a51218827168cdclaireho 35345569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 35355569331642446be05292e3e1f8a51218827168cdclaireho return error; 35365569331642446be05292e3e1f8a51218827168cdclaireho 35375569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 35385569331642446be05292e3e1f8a51218827168cdclaireho 35395569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 35405569331642446be05292e3e1f8a51218827168cdclaireho 35415569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 35425569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 35435569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &cpf2->Coverage, stream ) ) != HB_Err_Ok ) 35445569331642446be05292e3e1f8a51218827168cdclaireho return error; 35455569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 35465569331642446be05292e3e1f8a51218827168cdclaireho 35475569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 4L ) ) 35485569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 35495569331642446be05292e3e1f8a51218827168cdclaireho 35505569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 35515569331642446be05292e3e1f8a51218827168cdclaireho 35525569331642446be05292e3e1f8a51218827168cdclaireho /* `PosClassSetCount' is the upper limit for class values, thus we 35535569331642446be05292e3e1f8a51218827168cdclaireho read it now to make an additional safety check. */ 35545569331642446be05292e3e1f8a51218827168cdclaireho 35555569331642446be05292e3e1f8a51218827168cdclaireho count = cpf2->PosClassSetCount = GET_UShort(); 35565569331642446be05292e3e1f8a51218827168cdclaireho 35575569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 35585569331642446be05292e3e1f8a51218827168cdclaireho 35595569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 35605569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 35615569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_ClassDefinition( &cpf2->ClassDef, count, 35625569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 35635569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 35645569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 35655569331642446be05292e3e1f8a51218827168cdclaireho 35665569331642446be05292e3e1f8a51218827168cdclaireho cpf2->PosClassSet = NULL; 35675569331642446be05292e3e1f8a51218827168cdclaireho cpf2->MaxContextLength = 0; 35685569331642446be05292e3e1f8a51218827168cdclaireho 35695569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( cpf2->PosClassSet, count, HB_PosClassSet ) ) 35705569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 35715569331642446be05292e3e1f8a51218827168cdclaireho 35725569331642446be05292e3e1f8a51218827168cdclaireho pcs = cpf2->PosClassSet; 35735569331642446be05292e3e1f8a51218827168cdclaireho 35745569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 35755569331642446be05292e3e1f8a51218827168cdclaireho { 35765569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 35775569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 35785569331642446be05292e3e1f8a51218827168cdclaireho 35795569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 35805569331642446be05292e3e1f8a51218827168cdclaireho 35815569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 35825569331642446be05292e3e1f8a51218827168cdclaireho 35835569331642446be05292e3e1f8a51218827168cdclaireho if ( new_offset != base_offset ) /* not a NULL offset */ 35845569331642446be05292e3e1f8a51218827168cdclaireho { 35855569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 35865569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 35875569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_PosClassSet( cpf2, &pcs[n], 35885569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 35895569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 35905569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 35915569331642446be05292e3e1f8a51218827168cdclaireho } 35925569331642446be05292e3e1f8a51218827168cdclaireho else 35935569331642446be05292e3e1f8a51218827168cdclaireho { 35945569331642446be05292e3e1f8a51218827168cdclaireho /* we create a PosClassSet table with no entries */ 35955569331642446be05292e3e1f8a51218827168cdclaireho 35965569331642446be05292e3e1f8a51218827168cdclaireho cpf2->PosClassSet[n].PosClassRuleCount = 0; 35975569331642446be05292e3e1f8a51218827168cdclaireho cpf2->PosClassSet[n].PosClassRule = NULL; 35985569331642446be05292e3e1f8a51218827168cdclaireho } 35995569331642446be05292e3e1f8a51218827168cdclaireho } 36005569331642446be05292e3e1f8a51218827168cdclaireho 36015569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 36025569331642446be05292e3e1f8a51218827168cdclaireho 36035569331642446be05292e3e1f8a51218827168cdclairehoFail1: 36045569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; n++ ) 36055569331642446be05292e3e1f8a51218827168cdclaireho Free_PosClassSet( &pcs[m] ); 36065569331642446be05292e3e1f8a51218827168cdclaireho 36075569331642446be05292e3e1f8a51218827168cdclaireho FREE( pcs ); 36085569331642446be05292e3e1f8a51218827168cdclaireho 36095569331642446be05292e3e1f8a51218827168cdclairehoFail2: 36105569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_ClassDefinition( &cpf2->ClassDef ); 36115569331642446be05292e3e1f8a51218827168cdclaireho 36125569331642446be05292e3e1f8a51218827168cdclairehoFail3: 36135569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &cpf2->Coverage ); 36145569331642446be05292e3e1f8a51218827168cdclaireho return error; 36155569331642446be05292e3e1f8a51218827168cdclaireho} 36165569331642446be05292e3e1f8a51218827168cdclaireho 36175569331642446be05292e3e1f8a51218827168cdclaireho 36185569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_ContextPos2( HB_ContextPosFormat2* cpf2 ) 36195569331642446be05292e3e1f8a51218827168cdclaireho{ 36205569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 36215569331642446be05292e3e1f8a51218827168cdclaireho 36225569331642446be05292e3e1f8a51218827168cdclaireho HB_PosClassSet* pcs; 36235569331642446be05292e3e1f8a51218827168cdclaireho 36245569331642446be05292e3e1f8a51218827168cdclaireho 36255569331642446be05292e3e1f8a51218827168cdclaireho if ( cpf2->PosClassSet ) 36265569331642446be05292e3e1f8a51218827168cdclaireho { 36275569331642446be05292e3e1f8a51218827168cdclaireho count = cpf2->PosClassSetCount; 36285569331642446be05292e3e1f8a51218827168cdclaireho pcs = cpf2->PosClassSet; 36295569331642446be05292e3e1f8a51218827168cdclaireho 36305569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 36315569331642446be05292e3e1f8a51218827168cdclaireho Free_PosClassSet( &pcs[n] ); 36325569331642446be05292e3e1f8a51218827168cdclaireho 36335569331642446be05292e3e1f8a51218827168cdclaireho FREE( pcs ); 36345569331642446be05292e3e1f8a51218827168cdclaireho } 36355569331642446be05292e3e1f8a51218827168cdclaireho 36365569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_ClassDefinition( &cpf2->ClassDef ); 36375569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &cpf2->Coverage ); 36385569331642446be05292e3e1f8a51218827168cdclaireho} 36395569331642446be05292e3e1f8a51218827168cdclaireho 36405569331642446be05292e3e1f8a51218827168cdclaireho 36415569331642446be05292e3e1f8a51218827168cdclaireho/* ContextPosFormat3 */ 36425569331642446be05292e3e1f8a51218827168cdclaireho 36435569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_ContextPos3( HB_ContextPosFormat3* cpf3, 36445569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 36455569331642446be05292e3e1f8a51218827168cdclaireho{ 36465569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 36475569331642446be05292e3e1f8a51218827168cdclaireho 36485569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 36495569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 36505569331642446be05292e3e1f8a51218827168cdclaireho 36515569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage* c; 36525569331642446be05292e3e1f8a51218827168cdclaireho HB_PosLookupRecord* plr; 36535569331642446be05292e3e1f8a51218827168cdclaireho 36545569331642446be05292e3e1f8a51218827168cdclaireho 36555569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos() - 2L; 36565569331642446be05292e3e1f8a51218827168cdclaireho 36575569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 4L ) ) 36585569331642446be05292e3e1f8a51218827168cdclaireho return error; 36595569331642446be05292e3e1f8a51218827168cdclaireho 36605569331642446be05292e3e1f8a51218827168cdclaireho cpf3->GlyphCount = GET_UShort(); 36615569331642446be05292e3e1f8a51218827168cdclaireho cpf3->PosCount = GET_UShort(); 36625569331642446be05292e3e1f8a51218827168cdclaireho 36635569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 36645569331642446be05292e3e1f8a51218827168cdclaireho 36655569331642446be05292e3e1f8a51218827168cdclaireho cpf3->Coverage = NULL; 36665569331642446be05292e3e1f8a51218827168cdclaireho 36675569331642446be05292e3e1f8a51218827168cdclaireho count = cpf3->GlyphCount; 36685569331642446be05292e3e1f8a51218827168cdclaireho 36695569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( cpf3->Coverage, count, HB_Coverage ) ) 36705569331642446be05292e3e1f8a51218827168cdclaireho return error; 36715569331642446be05292e3e1f8a51218827168cdclaireho 36725569331642446be05292e3e1f8a51218827168cdclaireho c = cpf3->Coverage; 36735569331642446be05292e3e1f8a51218827168cdclaireho 36745569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 36755569331642446be05292e3e1f8a51218827168cdclaireho { 36765569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 36775569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 36785569331642446be05292e3e1f8a51218827168cdclaireho 36795569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 36805569331642446be05292e3e1f8a51218827168cdclaireho 36815569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 36825569331642446be05292e3e1f8a51218827168cdclaireho 36835569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 36845569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 36855569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &c[n], stream ) ) != HB_Err_Ok ) 36865569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 36875569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 36885569331642446be05292e3e1f8a51218827168cdclaireho } 36895569331642446be05292e3e1f8a51218827168cdclaireho 36905569331642446be05292e3e1f8a51218827168cdclaireho cpf3->PosLookupRecord = NULL; 36915569331642446be05292e3e1f8a51218827168cdclaireho 36925569331642446be05292e3e1f8a51218827168cdclaireho count = cpf3->PosCount; 36935569331642446be05292e3e1f8a51218827168cdclaireho 36945569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( cpf3->PosLookupRecord, count, HB_PosLookupRecord ) ) 36955569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 36965569331642446be05292e3e1f8a51218827168cdclaireho 36975569331642446be05292e3e1f8a51218827168cdclaireho plr = cpf3->PosLookupRecord; 36985569331642446be05292e3e1f8a51218827168cdclaireho 36995569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 4L ) ) 37005569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 37015569331642446be05292e3e1f8a51218827168cdclaireho 37025569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 37035569331642446be05292e3e1f8a51218827168cdclaireho { 37045569331642446be05292e3e1f8a51218827168cdclaireho plr[n].SequenceIndex = GET_UShort(); 37055569331642446be05292e3e1f8a51218827168cdclaireho plr[n].LookupListIndex = GET_UShort(); 37065569331642446be05292e3e1f8a51218827168cdclaireho } 37075569331642446be05292e3e1f8a51218827168cdclaireho 37085569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 37095569331642446be05292e3e1f8a51218827168cdclaireho 37105569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 37115569331642446be05292e3e1f8a51218827168cdclaireho 37125569331642446be05292e3e1f8a51218827168cdclairehoFail1: 37135569331642446be05292e3e1f8a51218827168cdclaireho FREE( plr ); 37145569331642446be05292e3e1f8a51218827168cdclaireho 37155569331642446be05292e3e1f8a51218827168cdclairehoFail2: 37165569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 37175569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &c[n] ); 37185569331642446be05292e3e1f8a51218827168cdclaireho 37195569331642446be05292e3e1f8a51218827168cdclaireho FREE( c ); 37205569331642446be05292e3e1f8a51218827168cdclaireho return error; 37215569331642446be05292e3e1f8a51218827168cdclaireho} 37225569331642446be05292e3e1f8a51218827168cdclaireho 37235569331642446be05292e3e1f8a51218827168cdclaireho 37245569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_ContextPos3( HB_ContextPosFormat3* cpf3 ) 37255569331642446be05292e3e1f8a51218827168cdclaireho{ 37265569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 37275569331642446be05292e3e1f8a51218827168cdclaireho 37285569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage* c; 37295569331642446be05292e3e1f8a51218827168cdclaireho 37305569331642446be05292e3e1f8a51218827168cdclaireho 37315569331642446be05292e3e1f8a51218827168cdclaireho FREE( cpf3->PosLookupRecord ); 37325569331642446be05292e3e1f8a51218827168cdclaireho 37335569331642446be05292e3e1f8a51218827168cdclaireho if ( cpf3->Coverage ) 37345569331642446be05292e3e1f8a51218827168cdclaireho { 37355569331642446be05292e3e1f8a51218827168cdclaireho count = cpf3->GlyphCount; 37365569331642446be05292e3e1f8a51218827168cdclaireho c = cpf3->Coverage; 37375569331642446be05292e3e1f8a51218827168cdclaireho 37385569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 37395569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &c[n] ); 37405569331642446be05292e3e1f8a51218827168cdclaireho 37415569331642446be05292e3e1f8a51218827168cdclaireho FREE( c ); 37425569331642446be05292e3e1f8a51218827168cdclaireho } 37435569331642446be05292e3e1f8a51218827168cdclaireho} 37445569331642446be05292e3e1f8a51218827168cdclaireho 37455569331642446be05292e3e1f8a51218827168cdclaireho 37465569331642446be05292e3e1f8a51218827168cdclaireho/* ContextPos */ 37475569331642446be05292e3e1f8a51218827168cdclaireho 37485569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_ContextPos( HB_GPOS_SubTable* st, 37495569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 37505569331642446be05292e3e1f8a51218827168cdclaireho{ 37515569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 37525569331642446be05292e3e1f8a51218827168cdclaireho HB_ContextPos* cp = &st->context; 37535569331642446be05292e3e1f8a51218827168cdclaireho 37545569331642446be05292e3e1f8a51218827168cdclaireho 37555569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 37565569331642446be05292e3e1f8a51218827168cdclaireho return error; 37575569331642446be05292e3e1f8a51218827168cdclaireho 37585569331642446be05292e3e1f8a51218827168cdclaireho cp->PosFormat = GET_UShort(); 37595569331642446be05292e3e1f8a51218827168cdclaireho 37605569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 37615569331642446be05292e3e1f8a51218827168cdclaireho 37625569331642446be05292e3e1f8a51218827168cdclaireho switch ( cp->PosFormat ) 37635569331642446be05292e3e1f8a51218827168cdclaireho { 37645569331642446be05292e3e1f8a51218827168cdclaireho case 1: 37655569331642446be05292e3e1f8a51218827168cdclaireho return Load_ContextPos1( &cp->cpf.cpf1, stream ); 37665569331642446be05292e3e1f8a51218827168cdclaireho 37675569331642446be05292e3e1f8a51218827168cdclaireho case 2: 37685569331642446be05292e3e1f8a51218827168cdclaireho return Load_ContextPos2( &cp->cpf.cpf2, stream ); 37695569331642446be05292e3e1f8a51218827168cdclaireho 37705569331642446be05292e3e1f8a51218827168cdclaireho case 3: 37715569331642446be05292e3e1f8a51218827168cdclaireho return Load_ContextPos3( &cp->cpf.cpf3, stream ); 37725569331642446be05292e3e1f8a51218827168cdclaireho 37735569331642446be05292e3e1f8a51218827168cdclaireho default: 37745569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable_Format); 37755569331642446be05292e3e1f8a51218827168cdclaireho } 37765569331642446be05292e3e1f8a51218827168cdclaireho 37775569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; /* never reached */ 37785569331642446be05292e3e1f8a51218827168cdclaireho} 37795569331642446be05292e3e1f8a51218827168cdclaireho 37805569331642446be05292e3e1f8a51218827168cdclaireho 37815569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_ContextPos( HB_GPOS_SubTable* st ) 37825569331642446be05292e3e1f8a51218827168cdclaireho{ 37835569331642446be05292e3e1f8a51218827168cdclaireho HB_ContextPos* cp = &st->context; 37845569331642446be05292e3e1f8a51218827168cdclaireho 37855569331642446be05292e3e1f8a51218827168cdclaireho switch ( cp->PosFormat ) 37865569331642446be05292e3e1f8a51218827168cdclaireho { 37875569331642446be05292e3e1f8a51218827168cdclaireho case 1: Free_ContextPos1( &cp->cpf.cpf1 ); break; 37885569331642446be05292e3e1f8a51218827168cdclaireho case 2: Free_ContextPos2( &cp->cpf.cpf2 ); break; 37895569331642446be05292e3e1f8a51218827168cdclaireho case 3: Free_ContextPos3( &cp->cpf.cpf3 ); break; 37905569331642446be05292e3e1f8a51218827168cdclaireho default: break; 37915569331642446be05292e3e1f8a51218827168cdclaireho } 37925569331642446be05292e3e1f8a51218827168cdclaireho} 37935569331642446be05292e3e1f8a51218827168cdclaireho 37945569331642446be05292e3e1f8a51218827168cdclaireho 37955569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Lookup_ContextPos1( GPOS_Instance* gpi, 37965569331642446be05292e3e1f8a51218827168cdclaireho HB_ContextPosFormat1* cpf1, 37975569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 37985569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort flags, 37995569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 38005569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 38015569331642446be05292e3e1f8a51218827168cdclaireho{ 38025569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort index, property; 38035569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort i, j, k, numpr; 38045569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 38055569331642446be05292e3e1f8a51218827168cdclaireho HB_GPOSHeader* gpos = gpi->gpos; 38065569331642446be05292e3e1f8a51218827168cdclaireho 38075569331642446be05292e3e1f8a51218827168cdclaireho HB_PosRule* pr; 38085569331642446be05292e3e1f8a51218827168cdclaireho HB_GDEFHeader* gdef; 38095569331642446be05292e3e1f8a51218827168cdclaireho 38105569331642446be05292e3e1f8a51218827168cdclaireho 38115569331642446be05292e3e1f8a51218827168cdclaireho gdef = gpos->gdef; 38125569331642446be05292e3e1f8a51218827168cdclaireho 38135569331642446be05292e3e1f8a51218827168cdclaireho if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) 38145569331642446be05292e3e1f8a51218827168cdclaireho return error; 38155569331642446be05292e3e1f8a51218827168cdclaireho 38165569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &cpf1->Coverage, IN_CURGLYPH(), &index ); 38175569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 38185569331642446be05292e3e1f8a51218827168cdclaireho return error; 38195569331642446be05292e3e1f8a51218827168cdclaireho 38205569331642446be05292e3e1f8a51218827168cdclaireho pr = cpf1->PosRuleSet[index].PosRule; 38215569331642446be05292e3e1f8a51218827168cdclaireho numpr = cpf1->PosRuleSet[index].PosRuleCount; 38225569331642446be05292e3e1f8a51218827168cdclaireho 38235569331642446be05292e3e1f8a51218827168cdclaireho for ( k = 0; k < numpr; k++ ) 38245569331642446be05292e3e1f8a51218827168cdclaireho { 38255569331642446be05292e3e1f8a51218827168cdclaireho if ( context_length != 0xFFFF && context_length < pr[k].GlyphCount ) 38265569331642446be05292e3e1f8a51218827168cdclaireho goto next_posrule; 38275569331642446be05292e3e1f8a51218827168cdclaireho 38285569331642446be05292e3e1f8a51218827168cdclaireho if ( buffer->in_pos + pr[k].GlyphCount > buffer->in_length ) 38295569331642446be05292e3e1f8a51218827168cdclaireho goto next_posrule; /* context is too long */ 38305569331642446be05292e3e1f8a51218827168cdclaireho 38315569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 1, j = buffer->in_pos + 1; i < pr[k].GlyphCount; i++, j++ ) 38325569331642446be05292e3e1f8a51218827168cdclaireho { 38335569331642446be05292e3e1f8a51218827168cdclaireho while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) 38345569331642446be05292e3e1f8a51218827168cdclaireho { 38355569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 38365569331642446be05292e3e1f8a51218827168cdclaireho return error; 38375569331642446be05292e3e1f8a51218827168cdclaireho 38385569331642446be05292e3e1f8a51218827168cdclaireho if ( j + pr[k].GlyphCount - i == (HB_Int)buffer->in_length ) 38395569331642446be05292e3e1f8a51218827168cdclaireho goto next_posrule; 38405569331642446be05292e3e1f8a51218827168cdclaireho j++; 38415569331642446be05292e3e1f8a51218827168cdclaireho } 38425569331642446be05292e3e1f8a51218827168cdclaireho 38435569331642446be05292e3e1f8a51218827168cdclaireho if ( IN_GLYPH( j ) != pr[k].Input[i - 1] ) 38445569331642446be05292e3e1f8a51218827168cdclaireho goto next_posrule; 38455569331642446be05292e3e1f8a51218827168cdclaireho } 38465569331642446be05292e3e1f8a51218827168cdclaireho 38475569331642446be05292e3e1f8a51218827168cdclaireho return Do_ContextPos( gpi, pr[k].GlyphCount, 38485569331642446be05292e3e1f8a51218827168cdclaireho pr[k].PosCount, pr[k].PosLookupRecord, 38495569331642446be05292e3e1f8a51218827168cdclaireho buffer, 38505569331642446be05292e3e1f8a51218827168cdclaireho nesting_level ); 38515569331642446be05292e3e1f8a51218827168cdclaireho 38525569331642446be05292e3e1f8a51218827168cdclaireho next_posrule: 38535569331642446be05292e3e1f8a51218827168cdclaireho ; 38545569331642446be05292e3e1f8a51218827168cdclaireho } 38555569331642446be05292e3e1f8a51218827168cdclaireho 38565569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 38575569331642446be05292e3e1f8a51218827168cdclaireho} 38585569331642446be05292e3e1f8a51218827168cdclaireho 38595569331642446be05292e3e1f8a51218827168cdclaireho 38605569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Lookup_ContextPos2( GPOS_Instance* gpi, 38615569331642446be05292e3e1f8a51218827168cdclaireho HB_ContextPosFormat2* cpf2, 38625569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 38635569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort flags, 38645569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 38655569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 38665569331642446be05292e3e1f8a51218827168cdclaireho{ 38675569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort index, property; 38685569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 38695569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort i, j, k, known_classes; 38705569331642446be05292e3e1f8a51218827168cdclaireho 38715569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* classes; 38725569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* cl; 38735569331642446be05292e3e1f8a51218827168cdclaireho HB_GPOSHeader* gpos = gpi->gpos; 38745569331642446be05292e3e1f8a51218827168cdclaireho 38755569331642446be05292e3e1f8a51218827168cdclaireho HB_PosClassSet* pcs; 38765569331642446be05292e3e1f8a51218827168cdclaireho HB_PosClassRule* pr; 38775569331642446be05292e3e1f8a51218827168cdclaireho HB_GDEFHeader* gdef; 38785569331642446be05292e3e1f8a51218827168cdclaireho 38795569331642446be05292e3e1f8a51218827168cdclaireho 38805569331642446be05292e3e1f8a51218827168cdclaireho gdef = gpos->gdef; 38815569331642446be05292e3e1f8a51218827168cdclaireho 38825569331642446be05292e3e1f8a51218827168cdclaireho if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) 38835569331642446be05292e3e1f8a51218827168cdclaireho return error; 38845569331642446be05292e3e1f8a51218827168cdclaireho 38855569331642446be05292e3e1f8a51218827168cdclaireho /* Note: The coverage table in format 2 doesn't give an index into 38865569331642446be05292e3e1f8a51218827168cdclaireho anything. It just lets us know whether or not we need to 38875569331642446be05292e3e1f8a51218827168cdclaireho do any lookup at all. */ 38885569331642446be05292e3e1f8a51218827168cdclaireho 38895569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &cpf2->Coverage, IN_CURGLYPH(), &index ); 38905569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 38915569331642446be05292e3e1f8a51218827168cdclaireho return error; 38925569331642446be05292e3e1f8a51218827168cdclaireho 38935569331642446be05292e3e1f8a51218827168cdclaireho if (cpf2->MaxContextLength < 1) 38945569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 38955569331642446be05292e3e1f8a51218827168cdclaireho 38965569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( classes, cpf2->MaxContextLength, HB_UShort ) ) 38975569331642446be05292e3e1f8a51218827168cdclaireho return error; 38985569331642446be05292e3e1f8a51218827168cdclaireho 38995569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Get_Class( &cpf2->ClassDef, IN_CURGLYPH(), 39005569331642446be05292e3e1f8a51218827168cdclaireho &classes[0], NULL ); 39015569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 39025569331642446be05292e3e1f8a51218827168cdclaireho goto End; 39035569331642446be05292e3e1f8a51218827168cdclaireho known_classes = 0; 39045569331642446be05292e3e1f8a51218827168cdclaireho 39055569331642446be05292e3e1f8a51218827168cdclaireho pcs = &cpf2->PosClassSet[classes[0]]; 39065569331642446be05292e3e1f8a51218827168cdclaireho if ( !pcs ) 39075569331642446be05292e3e1f8a51218827168cdclaireho { 39085569331642446be05292e3e1f8a51218827168cdclaireho error = ERR(HB_Err_Invalid_SubTable); 39095569331642446be05292e3e1f8a51218827168cdclaireho goto End; 39105569331642446be05292e3e1f8a51218827168cdclaireho } 39115569331642446be05292e3e1f8a51218827168cdclaireho 39125569331642446be05292e3e1f8a51218827168cdclaireho for ( k = 0; k < pcs->PosClassRuleCount; k++ ) 39135569331642446be05292e3e1f8a51218827168cdclaireho { 39145569331642446be05292e3e1f8a51218827168cdclaireho pr = &pcs->PosClassRule[k]; 39155569331642446be05292e3e1f8a51218827168cdclaireho 39165569331642446be05292e3e1f8a51218827168cdclaireho if ( context_length != 0xFFFF && context_length < pr->GlyphCount ) 39175569331642446be05292e3e1f8a51218827168cdclaireho goto next_posclassrule; 39185569331642446be05292e3e1f8a51218827168cdclaireho 39195569331642446be05292e3e1f8a51218827168cdclaireho if ( buffer->in_pos + pr->GlyphCount > buffer->in_length ) 39205569331642446be05292e3e1f8a51218827168cdclaireho goto next_posclassrule; /* context is too long */ 39215569331642446be05292e3e1f8a51218827168cdclaireho 39225569331642446be05292e3e1f8a51218827168cdclaireho cl = pr->Class; 39235569331642446be05292e3e1f8a51218827168cdclaireho 39245569331642446be05292e3e1f8a51218827168cdclaireho /* Start at 1 because [0] is implied */ 39255569331642446be05292e3e1f8a51218827168cdclaireho 39265569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 1, j = buffer->in_pos + 1; i < pr->GlyphCount; i++, j++ ) 39275569331642446be05292e3e1f8a51218827168cdclaireho { 39285569331642446be05292e3e1f8a51218827168cdclaireho while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) 39295569331642446be05292e3e1f8a51218827168cdclaireho { 39305569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 39315569331642446be05292e3e1f8a51218827168cdclaireho goto End; 39325569331642446be05292e3e1f8a51218827168cdclaireho 39335569331642446be05292e3e1f8a51218827168cdclaireho if ( j + pr->GlyphCount - i == (HB_Int)buffer->in_length ) 39345569331642446be05292e3e1f8a51218827168cdclaireho goto next_posclassrule; 39355569331642446be05292e3e1f8a51218827168cdclaireho j++; 39365569331642446be05292e3e1f8a51218827168cdclaireho } 39375569331642446be05292e3e1f8a51218827168cdclaireho 39385569331642446be05292e3e1f8a51218827168cdclaireho if ( i > known_classes ) 39395569331642446be05292e3e1f8a51218827168cdclaireho { 39405569331642446be05292e3e1f8a51218827168cdclaireho /* Keeps us from having to do this for each rule */ 39415569331642446be05292e3e1f8a51218827168cdclaireho 39425569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Get_Class( &cpf2->ClassDef, IN_GLYPH( j ), &classes[i], NULL ); 39435569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 39445569331642446be05292e3e1f8a51218827168cdclaireho goto End; 39455569331642446be05292e3e1f8a51218827168cdclaireho known_classes = i; 39465569331642446be05292e3e1f8a51218827168cdclaireho } 39475569331642446be05292e3e1f8a51218827168cdclaireho 39485569331642446be05292e3e1f8a51218827168cdclaireho if ( cl[i - 1] != classes[i] ) 39495569331642446be05292e3e1f8a51218827168cdclaireho goto next_posclassrule; 39505569331642446be05292e3e1f8a51218827168cdclaireho } 39515569331642446be05292e3e1f8a51218827168cdclaireho 39525569331642446be05292e3e1f8a51218827168cdclaireho error = Do_ContextPos( gpi, pr->GlyphCount, 39535569331642446be05292e3e1f8a51218827168cdclaireho pr->PosCount, pr->PosLookupRecord, 39545569331642446be05292e3e1f8a51218827168cdclaireho buffer, 39555569331642446be05292e3e1f8a51218827168cdclaireho nesting_level ); 39565569331642446be05292e3e1f8a51218827168cdclaireho goto End; 39575569331642446be05292e3e1f8a51218827168cdclaireho 39585569331642446be05292e3e1f8a51218827168cdclaireho next_posclassrule: 39595569331642446be05292e3e1f8a51218827168cdclaireho ; 39605569331642446be05292e3e1f8a51218827168cdclaireho } 39615569331642446be05292e3e1f8a51218827168cdclaireho 39625569331642446be05292e3e1f8a51218827168cdclaireho error = HB_Err_Not_Covered; 39635569331642446be05292e3e1f8a51218827168cdclaireho 39645569331642446be05292e3e1f8a51218827168cdclairehoEnd: 39655569331642446be05292e3e1f8a51218827168cdclaireho FREE( classes ); 39665569331642446be05292e3e1f8a51218827168cdclaireho return error; 39675569331642446be05292e3e1f8a51218827168cdclaireho} 39685569331642446be05292e3e1f8a51218827168cdclaireho 39695569331642446be05292e3e1f8a51218827168cdclaireho 39705569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Lookup_ContextPos3( GPOS_Instance* gpi, 39715569331642446be05292e3e1f8a51218827168cdclaireho HB_ContextPosFormat3* cpf3, 39725569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 39735569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort flags, 39745569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 39755569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 39765569331642446be05292e3e1f8a51218827168cdclaireho{ 39775569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 39785569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort index, i, j, property; 39795569331642446be05292e3e1f8a51218827168cdclaireho HB_GPOSHeader* gpos = gpi->gpos; 39805569331642446be05292e3e1f8a51218827168cdclaireho 39815569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage* c; 39825569331642446be05292e3e1f8a51218827168cdclaireho HB_GDEFHeader* gdef; 39835569331642446be05292e3e1f8a51218827168cdclaireho 39845569331642446be05292e3e1f8a51218827168cdclaireho 39855569331642446be05292e3e1f8a51218827168cdclaireho gdef = gpos->gdef; 39865569331642446be05292e3e1f8a51218827168cdclaireho 39875569331642446be05292e3e1f8a51218827168cdclaireho if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) 39885569331642446be05292e3e1f8a51218827168cdclaireho return error; 39895569331642446be05292e3e1f8a51218827168cdclaireho 39905569331642446be05292e3e1f8a51218827168cdclaireho if ( context_length != 0xFFFF && context_length < cpf3->GlyphCount ) 39915569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 39925569331642446be05292e3e1f8a51218827168cdclaireho 39935569331642446be05292e3e1f8a51218827168cdclaireho if ( buffer->in_pos + cpf3->GlyphCount > buffer->in_length ) 39945569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; /* context is too long */ 39955569331642446be05292e3e1f8a51218827168cdclaireho 39965569331642446be05292e3e1f8a51218827168cdclaireho c = cpf3->Coverage; 39975569331642446be05292e3e1f8a51218827168cdclaireho 39985569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 1, j = 1; i < cpf3->GlyphCount; i++, j++ ) 39995569331642446be05292e3e1f8a51218827168cdclaireho { 40005569331642446be05292e3e1f8a51218827168cdclaireho while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) 40015569331642446be05292e3e1f8a51218827168cdclaireho { 40025569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 40035569331642446be05292e3e1f8a51218827168cdclaireho return error; 40045569331642446be05292e3e1f8a51218827168cdclaireho 40055569331642446be05292e3e1f8a51218827168cdclaireho if ( j + cpf3->GlyphCount - i == (HB_Int)buffer->in_length ) 40065569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 40075569331642446be05292e3e1f8a51218827168cdclaireho j++; 40085569331642446be05292e3e1f8a51218827168cdclaireho } 40095569331642446be05292e3e1f8a51218827168cdclaireho 40105569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &c[i], IN_GLYPH( j ), &index ); 40115569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 40125569331642446be05292e3e1f8a51218827168cdclaireho return error; 40135569331642446be05292e3e1f8a51218827168cdclaireho } 40145569331642446be05292e3e1f8a51218827168cdclaireho 40155569331642446be05292e3e1f8a51218827168cdclaireho return Do_ContextPos( gpi, cpf3->GlyphCount, 40165569331642446be05292e3e1f8a51218827168cdclaireho cpf3->PosCount, cpf3->PosLookupRecord, 40175569331642446be05292e3e1f8a51218827168cdclaireho buffer, 40185569331642446be05292e3e1f8a51218827168cdclaireho nesting_level ); 40195569331642446be05292e3e1f8a51218827168cdclaireho} 40205569331642446be05292e3e1f8a51218827168cdclaireho 40215569331642446be05292e3e1f8a51218827168cdclaireho 40225569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Lookup_ContextPos( GPOS_Instance* gpi, 40235569331642446be05292e3e1f8a51218827168cdclaireho HB_GPOS_SubTable* st, 40245569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 40255569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort flags, 40265569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 40275569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 40285569331642446be05292e3e1f8a51218827168cdclaireho{ 40295569331642446be05292e3e1f8a51218827168cdclaireho HB_ContextPos* cp = &st->context; 40305569331642446be05292e3e1f8a51218827168cdclaireho 40315569331642446be05292e3e1f8a51218827168cdclaireho switch ( cp->PosFormat ) 40325569331642446be05292e3e1f8a51218827168cdclaireho { 40335569331642446be05292e3e1f8a51218827168cdclaireho case 1: 40345569331642446be05292e3e1f8a51218827168cdclaireho return Lookup_ContextPos1( gpi, &cp->cpf.cpf1, buffer, 40355569331642446be05292e3e1f8a51218827168cdclaireho flags, context_length, nesting_level ); 40365569331642446be05292e3e1f8a51218827168cdclaireho 40375569331642446be05292e3e1f8a51218827168cdclaireho case 2: 40385569331642446be05292e3e1f8a51218827168cdclaireho return Lookup_ContextPos2( gpi, &cp->cpf.cpf2, buffer, 40395569331642446be05292e3e1f8a51218827168cdclaireho flags, context_length, nesting_level ); 40405569331642446be05292e3e1f8a51218827168cdclaireho 40415569331642446be05292e3e1f8a51218827168cdclaireho case 3: 40425569331642446be05292e3e1f8a51218827168cdclaireho return Lookup_ContextPos3( gpi, &cp->cpf.cpf3, buffer, 40435569331642446be05292e3e1f8a51218827168cdclaireho flags, context_length, nesting_level ); 40445569331642446be05292e3e1f8a51218827168cdclaireho 40455569331642446be05292e3e1f8a51218827168cdclaireho default: 40465569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable_Format); 40475569331642446be05292e3e1f8a51218827168cdclaireho } 40485569331642446be05292e3e1f8a51218827168cdclaireho 40495569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; /* never reached */ 40505569331642446be05292e3e1f8a51218827168cdclaireho} 40515569331642446be05292e3e1f8a51218827168cdclaireho 40525569331642446be05292e3e1f8a51218827168cdclaireho 40535569331642446be05292e3e1f8a51218827168cdclaireho/* LookupType 8 */ 40545569331642446be05292e3e1f8a51218827168cdclaireho 40555569331642446be05292e3e1f8a51218827168cdclaireho/* ChainPosRule */ 40565569331642446be05292e3e1f8a51218827168cdclaireho 40575569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_ChainPosRule( HB_ChainPosRule* cpr, 40585569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 40595569331642446be05292e3e1f8a51218827168cdclaireho{ 40605569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 40615569331642446be05292e3e1f8a51218827168cdclaireho 40625569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 40635569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* b; 40645569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* i; 40655569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* l; 40665569331642446be05292e3e1f8a51218827168cdclaireho 40675569331642446be05292e3e1f8a51218827168cdclaireho HB_PosLookupRecord* plr; 40685569331642446be05292e3e1f8a51218827168cdclaireho 40695569331642446be05292e3e1f8a51218827168cdclaireho 40705569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 40715569331642446be05292e3e1f8a51218827168cdclaireho return error; 40725569331642446be05292e3e1f8a51218827168cdclaireho 40735569331642446be05292e3e1f8a51218827168cdclaireho cpr->BacktrackGlyphCount = GET_UShort(); 40745569331642446be05292e3e1f8a51218827168cdclaireho 40755569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 40765569331642446be05292e3e1f8a51218827168cdclaireho 40775569331642446be05292e3e1f8a51218827168cdclaireho cpr->Backtrack = NULL; 40785569331642446be05292e3e1f8a51218827168cdclaireho 40795569331642446be05292e3e1f8a51218827168cdclaireho count = cpr->BacktrackGlyphCount; 40805569331642446be05292e3e1f8a51218827168cdclaireho 40815569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( cpr->Backtrack, count, HB_UShort ) ) 40825569331642446be05292e3e1f8a51218827168cdclaireho return error; 40835569331642446be05292e3e1f8a51218827168cdclaireho 40845569331642446be05292e3e1f8a51218827168cdclaireho b = cpr->Backtrack; 40855569331642446be05292e3e1f8a51218827168cdclaireho 40865569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 2L ) ) 40875569331642446be05292e3e1f8a51218827168cdclaireho goto Fail4; 40885569331642446be05292e3e1f8a51218827168cdclaireho 40895569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 40905569331642446be05292e3e1f8a51218827168cdclaireho b[n] = GET_UShort(); 40915569331642446be05292e3e1f8a51218827168cdclaireho 40925569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 40935569331642446be05292e3e1f8a51218827168cdclaireho 40945569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 40955569331642446be05292e3e1f8a51218827168cdclaireho goto Fail4; 40965569331642446be05292e3e1f8a51218827168cdclaireho 40975569331642446be05292e3e1f8a51218827168cdclaireho cpr->InputGlyphCount = GET_UShort(); 40985569331642446be05292e3e1f8a51218827168cdclaireho 40995569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 41005569331642446be05292e3e1f8a51218827168cdclaireho 41015569331642446be05292e3e1f8a51218827168cdclaireho cpr->Input = NULL; 41025569331642446be05292e3e1f8a51218827168cdclaireho 41035569331642446be05292e3e1f8a51218827168cdclaireho count = cpr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */ 41045569331642446be05292e3e1f8a51218827168cdclaireho 41055569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( cpr->Input, count, HB_UShort ) ) 41065569331642446be05292e3e1f8a51218827168cdclaireho goto Fail4; 41075569331642446be05292e3e1f8a51218827168cdclaireho 41085569331642446be05292e3e1f8a51218827168cdclaireho i = cpr->Input; 41095569331642446be05292e3e1f8a51218827168cdclaireho 41105569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 2L ) ) 41115569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 41125569331642446be05292e3e1f8a51218827168cdclaireho 41135569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 41145569331642446be05292e3e1f8a51218827168cdclaireho i[n] = GET_UShort(); 41155569331642446be05292e3e1f8a51218827168cdclaireho 41165569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 41175569331642446be05292e3e1f8a51218827168cdclaireho 41185569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 41195569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 41205569331642446be05292e3e1f8a51218827168cdclaireho 41215569331642446be05292e3e1f8a51218827168cdclaireho cpr->LookaheadGlyphCount = GET_UShort(); 41225569331642446be05292e3e1f8a51218827168cdclaireho 41235569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 41245569331642446be05292e3e1f8a51218827168cdclaireho 41255569331642446be05292e3e1f8a51218827168cdclaireho cpr->Lookahead = NULL; 41265569331642446be05292e3e1f8a51218827168cdclaireho 41275569331642446be05292e3e1f8a51218827168cdclaireho count = cpr->LookaheadGlyphCount; 41285569331642446be05292e3e1f8a51218827168cdclaireho 41295569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( cpr->Lookahead, count, HB_UShort ) ) 41305569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 41315569331642446be05292e3e1f8a51218827168cdclaireho 41325569331642446be05292e3e1f8a51218827168cdclaireho l = cpr->Lookahead; 41335569331642446be05292e3e1f8a51218827168cdclaireho 41345569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 2L ) ) 41355569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 41365569331642446be05292e3e1f8a51218827168cdclaireho 41375569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 41385569331642446be05292e3e1f8a51218827168cdclaireho l[n] = GET_UShort(); 41395569331642446be05292e3e1f8a51218827168cdclaireho 41405569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 41415569331642446be05292e3e1f8a51218827168cdclaireho 41425569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 41435569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 41445569331642446be05292e3e1f8a51218827168cdclaireho 41455569331642446be05292e3e1f8a51218827168cdclaireho cpr->PosCount = GET_UShort(); 41465569331642446be05292e3e1f8a51218827168cdclaireho 41475569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 41485569331642446be05292e3e1f8a51218827168cdclaireho 41495569331642446be05292e3e1f8a51218827168cdclaireho cpr->PosLookupRecord = NULL; 41505569331642446be05292e3e1f8a51218827168cdclaireho 41515569331642446be05292e3e1f8a51218827168cdclaireho count = cpr->PosCount; 41525569331642446be05292e3e1f8a51218827168cdclaireho 41535569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( cpr->PosLookupRecord, count, HB_PosLookupRecord ) ) 41545569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 41555569331642446be05292e3e1f8a51218827168cdclaireho 41565569331642446be05292e3e1f8a51218827168cdclaireho plr = cpr->PosLookupRecord; 41575569331642446be05292e3e1f8a51218827168cdclaireho 41585569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 4L ) ) 41595569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 41605569331642446be05292e3e1f8a51218827168cdclaireho 41615569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 41625569331642446be05292e3e1f8a51218827168cdclaireho { 41635569331642446be05292e3e1f8a51218827168cdclaireho plr[n].SequenceIndex = GET_UShort(); 41645569331642446be05292e3e1f8a51218827168cdclaireho plr[n].LookupListIndex = GET_UShort(); 41655569331642446be05292e3e1f8a51218827168cdclaireho } 41665569331642446be05292e3e1f8a51218827168cdclaireho 41675569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 41685569331642446be05292e3e1f8a51218827168cdclaireho 41695569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 41705569331642446be05292e3e1f8a51218827168cdclaireho 41715569331642446be05292e3e1f8a51218827168cdclairehoFail1: 41725569331642446be05292e3e1f8a51218827168cdclaireho FREE( plr ); 41735569331642446be05292e3e1f8a51218827168cdclaireho 41745569331642446be05292e3e1f8a51218827168cdclairehoFail2: 41755569331642446be05292e3e1f8a51218827168cdclaireho FREE( l ); 41765569331642446be05292e3e1f8a51218827168cdclaireho 41775569331642446be05292e3e1f8a51218827168cdclairehoFail3: 41785569331642446be05292e3e1f8a51218827168cdclaireho FREE( i ); 41795569331642446be05292e3e1f8a51218827168cdclaireho 41805569331642446be05292e3e1f8a51218827168cdclairehoFail4: 41815569331642446be05292e3e1f8a51218827168cdclaireho FREE( b ); 41825569331642446be05292e3e1f8a51218827168cdclaireho return error; 41835569331642446be05292e3e1f8a51218827168cdclaireho} 41845569331642446be05292e3e1f8a51218827168cdclaireho 41855569331642446be05292e3e1f8a51218827168cdclaireho 41865569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_ChainPosRule( HB_ChainPosRule* cpr ) 41875569331642446be05292e3e1f8a51218827168cdclaireho{ 41885569331642446be05292e3e1f8a51218827168cdclaireho FREE( cpr->PosLookupRecord ); 41895569331642446be05292e3e1f8a51218827168cdclaireho FREE( cpr->Lookahead ); 41905569331642446be05292e3e1f8a51218827168cdclaireho FREE( cpr->Input ); 41915569331642446be05292e3e1f8a51218827168cdclaireho FREE( cpr->Backtrack ); 41925569331642446be05292e3e1f8a51218827168cdclaireho} 41935569331642446be05292e3e1f8a51218827168cdclaireho 41945569331642446be05292e3e1f8a51218827168cdclaireho 41955569331642446be05292e3e1f8a51218827168cdclaireho/* ChainPosRuleSet */ 41965569331642446be05292e3e1f8a51218827168cdclaireho 41975569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_ChainPosRuleSet( HB_ChainPosRuleSet* cprs, 41985569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 41995569331642446be05292e3e1f8a51218827168cdclaireho{ 42005569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 42015569331642446be05292e3e1f8a51218827168cdclaireho 42025569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, m, count; 42035569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 42045569331642446be05292e3e1f8a51218827168cdclaireho 42055569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainPosRule* cpr; 42065569331642446be05292e3e1f8a51218827168cdclaireho 42075569331642446be05292e3e1f8a51218827168cdclaireho 42085569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 42095569331642446be05292e3e1f8a51218827168cdclaireho 42105569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 42115569331642446be05292e3e1f8a51218827168cdclaireho return error; 42125569331642446be05292e3e1f8a51218827168cdclaireho 42135569331642446be05292e3e1f8a51218827168cdclaireho count = cprs->ChainPosRuleCount = GET_UShort(); 42145569331642446be05292e3e1f8a51218827168cdclaireho 42155569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 42165569331642446be05292e3e1f8a51218827168cdclaireho 42175569331642446be05292e3e1f8a51218827168cdclaireho cprs->ChainPosRule = NULL; 42185569331642446be05292e3e1f8a51218827168cdclaireho 42195569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( cprs->ChainPosRule, count, HB_ChainPosRule ) ) 42205569331642446be05292e3e1f8a51218827168cdclaireho return error; 42215569331642446be05292e3e1f8a51218827168cdclaireho 42225569331642446be05292e3e1f8a51218827168cdclaireho cpr = cprs->ChainPosRule; 42235569331642446be05292e3e1f8a51218827168cdclaireho 42245569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 42255569331642446be05292e3e1f8a51218827168cdclaireho { 42265569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 42275569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 42285569331642446be05292e3e1f8a51218827168cdclaireho 42295569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 42305569331642446be05292e3e1f8a51218827168cdclaireho 42315569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 42325569331642446be05292e3e1f8a51218827168cdclaireho 42335569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 42345569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 42355569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_ChainPosRule( &cpr[n], stream ) ) != HB_Err_Ok ) 42365569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 42375569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 42385569331642446be05292e3e1f8a51218827168cdclaireho } 42395569331642446be05292e3e1f8a51218827168cdclaireho 42405569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 42415569331642446be05292e3e1f8a51218827168cdclaireho 42425569331642446be05292e3e1f8a51218827168cdclairehoFail: 42435569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; m++ ) 42445569331642446be05292e3e1f8a51218827168cdclaireho Free_ChainPosRule( &cpr[m] ); 42455569331642446be05292e3e1f8a51218827168cdclaireho 42465569331642446be05292e3e1f8a51218827168cdclaireho FREE( cpr ); 42475569331642446be05292e3e1f8a51218827168cdclaireho return error; 42485569331642446be05292e3e1f8a51218827168cdclaireho} 42495569331642446be05292e3e1f8a51218827168cdclaireho 42505569331642446be05292e3e1f8a51218827168cdclaireho 42515569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_ChainPosRuleSet( HB_ChainPosRuleSet* cprs ) 42525569331642446be05292e3e1f8a51218827168cdclaireho{ 42535569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 42545569331642446be05292e3e1f8a51218827168cdclaireho 42555569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainPosRule* cpr; 42565569331642446be05292e3e1f8a51218827168cdclaireho 42575569331642446be05292e3e1f8a51218827168cdclaireho 42585569331642446be05292e3e1f8a51218827168cdclaireho if ( cprs->ChainPosRule ) 42595569331642446be05292e3e1f8a51218827168cdclaireho { 42605569331642446be05292e3e1f8a51218827168cdclaireho count = cprs->ChainPosRuleCount; 42615569331642446be05292e3e1f8a51218827168cdclaireho cpr = cprs->ChainPosRule; 42625569331642446be05292e3e1f8a51218827168cdclaireho 42635569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 42645569331642446be05292e3e1f8a51218827168cdclaireho Free_ChainPosRule( &cpr[n] ); 42655569331642446be05292e3e1f8a51218827168cdclaireho 42665569331642446be05292e3e1f8a51218827168cdclaireho FREE( cpr ); 42675569331642446be05292e3e1f8a51218827168cdclaireho } 42685569331642446be05292e3e1f8a51218827168cdclaireho} 42695569331642446be05292e3e1f8a51218827168cdclaireho 42705569331642446be05292e3e1f8a51218827168cdclaireho 42715569331642446be05292e3e1f8a51218827168cdclaireho/* ChainContextPosFormat1 */ 42725569331642446be05292e3e1f8a51218827168cdclaireho 42735569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_ChainContextPos1( HB_ChainContextPosFormat1* ccpf1, 42745569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 42755569331642446be05292e3e1f8a51218827168cdclaireho{ 42765569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 42775569331642446be05292e3e1f8a51218827168cdclaireho 42785569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, m, count; 42795569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 42805569331642446be05292e3e1f8a51218827168cdclaireho 42815569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainPosRuleSet* cprs; 42825569331642446be05292e3e1f8a51218827168cdclaireho 42835569331642446be05292e3e1f8a51218827168cdclaireho 42845569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos() - 2L; 42855569331642446be05292e3e1f8a51218827168cdclaireho 42865569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 42875569331642446be05292e3e1f8a51218827168cdclaireho return error; 42885569331642446be05292e3e1f8a51218827168cdclaireho 42895569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 42905569331642446be05292e3e1f8a51218827168cdclaireho 42915569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 42925569331642446be05292e3e1f8a51218827168cdclaireho 42935569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 42945569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 42955569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &ccpf1->Coverage, stream ) ) != HB_Err_Ok ) 42965569331642446be05292e3e1f8a51218827168cdclaireho return error; 42975569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 42985569331642446be05292e3e1f8a51218827168cdclaireho 42995569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 43005569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 43015569331642446be05292e3e1f8a51218827168cdclaireho 43025569331642446be05292e3e1f8a51218827168cdclaireho count = ccpf1->ChainPosRuleSetCount = GET_UShort(); 43035569331642446be05292e3e1f8a51218827168cdclaireho 43045569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 43055569331642446be05292e3e1f8a51218827168cdclaireho 43065569331642446be05292e3e1f8a51218827168cdclaireho ccpf1->ChainPosRuleSet = NULL; 43075569331642446be05292e3e1f8a51218827168cdclaireho 43085569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( ccpf1->ChainPosRuleSet, count, HB_ChainPosRuleSet ) ) 43095569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 43105569331642446be05292e3e1f8a51218827168cdclaireho 43115569331642446be05292e3e1f8a51218827168cdclaireho cprs = ccpf1->ChainPosRuleSet; 43125569331642446be05292e3e1f8a51218827168cdclaireho 43135569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 43145569331642446be05292e3e1f8a51218827168cdclaireho { 43155569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 43165569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 43175569331642446be05292e3e1f8a51218827168cdclaireho 43185569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 43195569331642446be05292e3e1f8a51218827168cdclaireho 43205569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 43215569331642446be05292e3e1f8a51218827168cdclaireho 43225569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 43235569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 43245569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_ChainPosRuleSet( &cprs[n], stream ) ) != HB_Err_Ok ) 43255569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 43265569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 43275569331642446be05292e3e1f8a51218827168cdclaireho } 43285569331642446be05292e3e1f8a51218827168cdclaireho 43295569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 43305569331642446be05292e3e1f8a51218827168cdclaireho 43315569331642446be05292e3e1f8a51218827168cdclairehoFail1: 43325569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; m++ ) 43335569331642446be05292e3e1f8a51218827168cdclaireho Free_ChainPosRuleSet( &cprs[m] ); 43345569331642446be05292e3e1f8a51218827168cdclaireho 43355569331642446be05292e3e1f8a51218827168cdclaireho FREE( cprs ); 43365569331642446be05292e3e1f8a51218827168cdclaireho 43375569331642446be05292e3e1f8a51218827168cdclairehoFail2: 43385569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &ccpf1->Coverage ); 43395569331642446be05292e3e1f8a51218827168cdclaireho return error; 43405569331642446be05292e3e1f8a51218827168cdclaireho} 43415569331642446be05292e3e1f8a51218827168cdclaireho 43425569331642446be05292e3e1f8a51218827168cdclaireho 43435569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_ChainContextPos1( HB_ChainContextPosFormat1* ccpf1 ) 43445569331642446be05292e3e1f8a51218827168cdclaireho{ 43455569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 43465569331642446be05292e3e1f8a51218827168cdclaireho 43475569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainPosRuleSet* cprs; 43485569331642446be05292e3e1f8a51218827168cdclaireho 43495569331642446be05292e3e1f8a51218827168cdclaireho 43505569331642446be05292e3e1f8a51218827168cdclaireho if ( ccpf1->ChainPosRuleSet ) 43515569331642446be05292e3e1f8a51218827168cdclaireho { 43525569331642446be05292e3e1f8a51218827168cdclaireho count = ccpf1->ChainPosRuleSetCount; 43535569331642446be05292e3e1f8a51218827168cdclaireho cprs = ccpf1->ChainPosRuleSet; 43545569331642446be05292e3e1f8a51218827168cdclaireho 43555569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 43565569331642446be05292e3e1f8a51218827168cdclaireho Free_ChainPosRuleSet( &cprs[n] ); 43575569331642446be05292e3e1f8a51218827168cdclaireho 43585569331642446be05292e3e1f8a51218827168cdclaireho FREE( cprs ); 43595569331642446be05292e3e1f8a51218827168cdclaireho } 43605569331642446be05292e3e1f8a51218827168cdclaireho 43615569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &ccpf1->Coverage ); 43625569331642446be05292e3e1f8a51218827168cdclaireho} 43635569331642446be05292e3e1f8a51218827168cdclaireho 43645569331642446be05292e3e1f8a51218827168cdclaireho 43655569331642446be05292e3e1f8a51218827168cdclaireho/* ChainPosClassRule */ 43665569331642446be05292e3e1f8a51218827168cdclaireho 43675569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_ChainPosClassRule( 43685569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainContextPosFormat2* ccpf2, 43695569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainPosClassRule* cpcr, 43705569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 43715569331642446be05292e3e1f8a51218827168cdclaireho{ 43725569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 43735569331642446be05292e3e1f8a51218827168cdclaireho 43745569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 43755569331642446be05292e3e1f8a51218827168cdclaireho 43765569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* b; 43775569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* i; 43785569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* l; 43795569331642446be05292e3e1f8a51218827168cdclaireho HB_PosLookupRecord* plr; 43805569331642446be05292e3e1f8a51218827168cdclaireho 43815569331642446be05292e3e1f8a51218827168cdclaireho 43825569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 43835569331642446be05292e3e1f8a51218827168cdclaireho return error; 43845569331642446be05292e3e1f8a51218827168cdclaireho 43855569331642446be05292e3e1f8a51218827168cdclaireho cpcr->BacktrackGlyphCount = GET_UShort(); 43865569331642446be05292e3e1f8a51218827168cdclaireho 43875569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 43885569331642446be05292e3e1f8a51218827168cdclaireho 43895569331642446be05292e3e1f8a51218827168cdclaireho if ( cpcr->BacktrackGlyphCount > ccpf2->MaxBacktrackLength ) 43905569331642446be05292e3e1f8a51218827168cdclaireho ccpf2->MaxBacktrackLength = cpcr->BacktrackGlyphCount; 43915569331642446be05292e3e1f8a51218827168cdclaireho 43925569331642446be05292e3e1f8a51218827168cdclaireho cpcr->Backtrack = NULL; 43935569331642446be05292e3e1f8a51218827168cdclaireho 43945569331642446be05292e3e1f8a51218827168cdclaireho count = cpcr->BacktrackGlyphCount; 43955569331642446be05292e3e1f8a51218827168cdclaireho 43965569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( cpcr->Backtrack, count, HB_UShort ) ) 43975569331642446be05292e3e1f8a51218827168cdclaireho return error; 43985569331642446be05292e3e1f8a51218827168cdclaireho 43995569331642446be05292e3e1f8a51218827168cdclaireho b = cpcr->Backtrack; 44005569331642446be05292e3e1f8a51218827168cdclaireho 44015569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 2L ) ) 44025569331642446be05292e3e1f8a51218827168cdclaireho goto Fail4; 44035569331642446be05292e3e1f8a51218827168cdclaireho 44045569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 44055569331642446be05292e3e1f8a51218827168cdclaireho b[n] = GET_UShort(); 44065569331642446be05292e3e1f8a51218827168cdclaireho 44075569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 44085569331642446be05292e3e1f8a51218827168cdclaireho 44095569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 44105569331642446be05292e3e1f8a51218827168cdclaireho goto Fail4; 44115569331642446be05292e3e1f8a51218827168cdclaireho 44125569331642446be05292e3e1f8a51218827168cdclaireho cpcr->InputGlyphCount = GET_UShort(); 44135569331642446be05292e3e1f8a51218827168cdclaireho 44145569331642446be05292e3e1f8a51218827168cdclaireho if ( cpcr->InputGlyphCount > ccpf2->MaxInputLength ) 44155569331642446be05292e3e1f8a51218827168cdclaireho ccpf2->MaxInputLength = cpcr->InputGlyphCount; 44165569331642446be05292e3e1f8a51218827168cdclaireho 44175569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 44185569331642446be05292e3e1f8a51218827168cdclaireho 44195569331642446be05292e3e1f8a51218827168cdclaireho cpcr->Input = NULL; 44205569331642446be05292e3e1f8a51218827168cdclaireho 44215569331642446be05292e3e1f8a51218827168cdclaireho count = cpcr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */ 44225569331642446be05292e3e1f8a51218827168cdclaireho 44235569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( cpcr->Input, count, HB_UShort ) ) 44245569331642446be05292e3e1f8a51218827168cdclaireho goto Fail4; 44255569331642446be05292e3e1f8a51218827168cdclaireho 44265569331642446be05292e3e1f8a51218827168cdclaireho i = cpcr->Input; 44275569331642446be05292e3e1f8a51218827168cdclaireho 44285569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 2L ) ) 44295569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 44305569331642446be05292e3e1f8a51218827168cdclaireho 44315569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 44325569331642446be05292e3e1f8a51218827168cdclaireho i[n] = GET_UShort(); 44335569331642446be05292e3e1f8a51218827168cdclaireho 44345569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 44355569331642446be05292e3e1f8a51218827168cdclaireho 44365569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 44375569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 44385569331642446be05292e3e1f8a51218827168cdclaireho 44395569331642446be05292e3e1f8a51218827168cdclaireho cpcr->LookaheadGlyphCount = GET_UShort(); 44405569331642446be05292e3e1f8a51218827168cdclaireho 44415569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 44425569331642446be05292e3e1f8a51218827168cdclaireho 44435569331642446be05292e3e1f8a51218827168cdclaireho if ( cpcr->LookaheadGlyphCount > ccpf2->MaxLookaheadLength ) 44445569331642446be05292e3e1f8a51218827168cdclaireho ccpf2->MaxLookaheadLength = cpcr->LookaheadGlyphCount; 44455569331642446be05292e3e1f8a51218827168cdclaireho 44465569331642446be05292e3e1f8a51218827168cdclaireho cpcr->Lookahead = NULL; 44475569331642446be05292e3e1f8a51218827168cdclaireho 44485569331642446be05292e3e1f8a51218827168cdclaireho count = cpcr->LookaheadGlyphCount; 44495569331642446be05292e3e1f8a51218827168cdclaireho 44505569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( cpcr->Lookahead, count, HB_UShort ) ) 44515569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 44525569331642446be05292e3e1f8a51218827168cdclaireho 44535569331642446be05292e3e1f8a51218827168cdclaireho l = cpcr->Lookahead; 44545569331642446be05292e3e1f8a51218827168cdclaireho 44555569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 2L ) ) 44565569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 44575569331642446be05292e3e1f8a51218827168cdclaireho 44585569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 44595569331642446be05292e3e1f8a51218827168cdclaireho l[n] = GET_UShort(); 44605569331642446be05292e3e1f8a51218827168cdclaireho 44615569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 44625569331642446be05292e3e1f8a51218827168cdclaireho 44635569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 44645569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 44655569331642446be05292e3e1f8a51218827168cdclaireho 44665569331642446be05292e3e1f8a51218827168cdclaireho cpcr->PosCount = GET_UShort(); 44675569331642446be05292e3e1f8a51218827168cdclaireho 44685569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 44695569331642446be05292e3e1f8a51218827168cdclaireho 44705569331642446be05292e3e1f8a51218827168cdclaireho cpcr->PosLookupRecord = NULL; 44715569331642446be05292e3e1f8a51218827168cdclaireho 44725569331642446be05292e3e1f8a51218827168cdclaireho count = cpcr->PosCount; 44735569331642446be05292e3e1f8a51218827168cdclaireho 44745569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( cpcr->PosLookupRecord, count, HB_PosLookupRecord ) ) 44755569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 44765569331642446be05292e3e1f8a51218827168cdclaireho 44775569331642446be05292e3e1f8a51218827168cdclaireho plr = cpcr->PosLookupRecord; 44785569331642446be05292e3e1f8a51218827168cdclaireho 44795569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 4L ) ) 44805569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 44815569331642446be05292e3e1f8a51218827168cdclaireho 44825569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 44835569331642446be05292e3e1f8a51218827168cdclaireho { 44845569331642446be05292e3e1f8a51218827168cdclaireho plr[n].SequenceIndex = GET_UShort(); 44855569331642446be05292e3e1f8a51218827168cdclaireho plr[n].LookupListIndex = GET_UShort(); 44865569331642446be05292e3e1f8a51218827168cdclaireho } 44875569331642446be05292e3e1f8a51218827168cdclaireho 44885569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 44895569331642446be05292e3e1f8a51218827168cdclaireho 44905569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 44915569331642446be05292e3e1f8a51218827168cdclaireho 44925569331642446be05292e3e1f8a51218827168cdclairehoFail1: 44935569331642446be05292e3e1f8a51218827168cdclaireho FREE( plr ); 44945569331642446be05292e3e1f8a51218827168cdclaireho 44955569331642446be05292e3e1f8a51218827168cdclairehoFail2: 44965569331642446be05292e3e1f8a51218827168cdclaireho FREE( l ); 44975569331642446be05292e3e1f8a51218827168cdclaireho 44985569331642446be05292e3e1f8a51218827168cdclairehoFail3: 44995569331642446be05292e3e1f8a51218827168cdclaireho FREE( i ); 45005569331642446be05292e3e1f8a51218827168cdclaireho 45015569331642446be05292e3e1f8a51218827168cdclairehoFail4: 45025569331642446be05292e3e1f8a51218827168cdclaireho FREE( b ); 45035569331642446be05292e3e1f8a51218827168cdclaireho return error; 45045569331642446be05292e3e1f8a51218827168cdclaireho} 45055569331642446be05292e3e1f8a51218827168cdclaireho 45065569331642446be05292e3e1f8a51218827168cdclaireho 45075569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_ChainPosClassRule( HB_ChainPosClassRule* cpcr ) 45085569331642446be05292e3e1f8a51218827168cdclaireho{ 45095569331642446be05292e3e1f8a51218827168cdclaireho FREE( cpcr->PosLookupRecord ); 45105569331642446be05292e3e1f8a51218827168cdclaireho FREE( cpcr->Lookahead ); 45115569331642446be05292e3e1f8a51218827168cdclaireho FREE( cpcr->Input ); 45125569331642446be05292e3e1f8a51218827168cdclaireho FREE( cpcr->Backtrack ); 45135569331642446be05292e3e1f8a51218827168cdclaireho} 45145569331642446be05292e3e1f8a51218827168cdclaireho 45155569331642446be05292e3e1f8a51218827168cdclaireho 45165569331642446be05292e3e1f8a51218827168cdclaireho/* PosClassSet */ 45175569331642446be05292e3e1f8a51218827168cdclaireho 45185569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_ChainPosClassSet( 45195569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainContextPosFormat2* ccpf2, 45205569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainPosClassSet* cpcs, 45215569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 45225569331642446be05292e3e1f8a51218827168cdclaireho{ 45235569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 45245569331642446be05292e3e1f8a51218827168cdclaireho 45255569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, m, count; 45265569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 45275569331642446be05292e3e1f8a51218827168cdclaireho 45285569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainPosClassRule* cpcr; 45295569331642446be05292e3e1f8a51218827168cdclaireho 45305569331642446be05292e3e1f8a51218827168cdclaireho 45315569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos(); 45325569331642446be05292e3e1f8a51218827168cdclaireho 45335569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 45345569331642446be05292e3e1f8a51218827168cdclaireho return error; 45355569331642446be05292e3e1f8a51218827168cdclaireho 45365569331642446be05292e3e1f8a51218827168cdclaireho count = cpcs->ChainPosClassRuleCount = GET_UShort(); 45375569331642446be05292e3e1f8a51218827168cdclaireho 45385569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 45395569331642446be05292e3e1f8a51218827168cdclaireho 45405569331642446be05292e3e1f8a51218827168cdclaireho cpcs->ChainPosClassRule = NULL; 45415569331642446be05292e3e1f8a51218827168cdclaireho 45425569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( cpcs->ChainPosClassRule, count, 45435569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainPosClassRule ) ) 45445569331642446be05292e3e1f8a51218827168cdclaireho return error; 45455569331642446be05292e3e1f8a51218827168cdclaireho 45465569331642446be05292e3e1f8a51218827168cdclaireho cpcr = cpcs->ChainPosClassRule; 45475569331642446be05292e3e1f8a51218827168cdclaireho 45485569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 45495569331642446be05292e3e1f8a51218827168cdclaireho { 45505569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 45515569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 45525569331642446be05292e3e1f8a51218827168cdclaireho 45535569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 45545569331642446be05292e3e1f8a51218827168cdclaireho 45555569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 45565569331642446be05292e3e1f8a51218827168cdclaireho 45575569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 45585569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 45595569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_ChainPosClassRule( ccpf2, &cpcr[n], 45605569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 45615569331642446be05292e3e1f8a51218827168cdclaireho goto Fail; 45625569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 45635569331642446be05292e3e1f8a51218827168cdclaireho } 45645569331642446be05292e3e1f8a51218827168cdclaireho 45655569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 45665569331642446be05292e3e1f8a51218827168cdclaireho 45675569331642446be05292e3e1f8a51218827168cdclairehoFail: 45685569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; m++ ) 45695569331642446be05292e3e1f8a51218827168cdclaireho Free_ChainPosClassRule( &cpcr[m] ); 45705569331642446be05292e3e1f8a51218827168cdclaireho 45715569331642446be05292e3e1f8a51218827168cdclaireho FREE( cpcr ); 45725569331642446be05292e3e1f8a51218827168cdclaireho return error; 45735569331642446be05292e3e1f8a51218827168cdclaireho} 45745569331642446be05292e3e1f8a51218827168cdclaireho 45755569331642446be05292e3e1f8a51218827168cdclaireho 45765569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_ChainPosClassSet( HB_ChainPosClassSet* cpcs ) 45775569331642446be05292e3e1f8a51218827168cdclaireho{ 45785569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 45795569331642446be05292e3e1f8a51218827168cdclaireho 45805569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainPosClassRule* cpcr; 45815569331642446be05292e3e1f8a51218827168cdclaireho 45825569331642446be05292e3e1f8a51218827168cdclaireho 45835569331642446be05292e3e1f8a51218827168cdclaireho if ( cpcs->ChainPosClassRule ) 45845569331642446be05292e3e1f8a51218827168cdclaireho { 45855569331642446be05292e3e1f8a51218827168cdclaireho count = cpcs->ChainPosClassRuleCount; 45865569331642446be05292e3e1f8a51218827168cdclaireho cpcr = cpcs->ChainPosClassRule; 45875569331642446be05292e3e1f8a51218827168cdclaireho 45885569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 45895569331642446be05292e3e1f8a51218827168cdclaireho Free_ChainPosClassRule( &cpcr[n] ); 45905569331642446be05292e3e1f8a51218827168cdclaireho 45915569331642446be05292e3e1f8a51218827168cdclaireho FREE( cpcr ); 45925569331642446be05292e3e1f8a51218827168cdclaireho } 45935569331642446be05292e3e1f8a51218827168cdclaireho} 45945569331642446be05292e3e1f8a51218827168cdclaireho 45955569331642446be05292e3e1f8a51218827168cdclaireho 45965569331642446be05292e3e1f8a51218827168cdclaireho/* ChainContextPosFormat2 */ 45975569331642446be05292e3e1f8a51218827168cdclaireho 45985569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_ChainContextPos2( HB_ChainContextPosFormat2* ccpf2, 45995569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 46005569331642446be05292e3e1f8a51218827168cdclaireho{ 46015569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 46025569331642446be05292e3e1f8a51218827168cdclaireho 46035569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, m, count; 46045569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 46055569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt backtrack_offset, input_offset, lookahead_offset; 46065569331642446be05292e3e1f8a51218827168cdclaireho 46075569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainPosClassSet* cpcs; 46085569331642446be05292e3e1f8a51218827168cdclaireho 46095569331642446be05292e3e1f8a51218827168cdclaireho 46105569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos() - 2; 46115569331642446be05292e3e1f8a51218827168cdclaireho 46125569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 46135569331642446be05292e3e1f8a51218827168cdclaireho return error; 46145569331642446be05292e3e1f8a51218827168cdclaireho 46155569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 46165569331642446be05292e3e1f8a51218827168cdclaireho 46175569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 46185569331642446be05292e3e1f8a51218827168cdclaireho 46195569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 46205569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 46215569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &ccpf2->Coverage, stream ) ) != HB_Err_Ok ) 46225569331642446be05292e3e1f8a51218827168cdclaireho return error; 46235569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 46245569331642446be05292e3e1f8a51218827168cdclaireho 46255569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 8L ) ) 46265569331642446be05292e3e1f8a51218827168cdclaireho goto Fail5; 46275569331642446be05292e3e1f8a51218827168cdclaireho 46285569331642446be05292e3e1f8a51218827168cdclaireho backtrack_offset = GET_UShort(); 46295569331642446be05292e3e1f8a51218827168cdclaireho input_offset = GET_UShort(); 46305569331642446be05292e3e1f8a51218827168cdclaireho lookahead_offset = GET_UShort(); 46315569331642446be05292e3e1f8a51218827168cdclaireho 46325569331642446be05292e3e1f8a51218827168cdclaireho /* `ChainPosClassSetCount' is the upper limit for input class values, 46335569331642446be05292e3e1f8a51218827168cdclaireho thus we read it now to make an additional safety check. No limit 46345569331642446be05292e3e1f8a51218827168cdclaireho is known or needed for the other two class definitions */ 46355569331642446be05292e3e1f8a51218827168cdclaireho 46365569331642446be05292e3e1f8a51218827168cdclaireho count = ccpf2->ChainPosClassSetCount = GET_UShort(); 46375569331642446be05292e3e1f8a51218827168cdclaireho 46385569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 46395569331642446be05292e3e1f8a51218827168cdclaireho 46405569331642446be05292e3e1f8a51218827168cdclaireho if ( ( error = _HB_OPEN_Load_EmptyOrClassDefinition( &ccpf2->BacktrackClassDef, 65535, 46415569331642446be05292e3e1f8a51218827168cdclaireho backtrack_offset, base_offset, 46425569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 46435569331642446be05292e3e1f8a51218827168cdclaireho goto Fail5; 46445569331642446be05292e3e1f8a51218827168cdclaireho if ( ( error = _HB_OPEN_Load_EmptyOrClassDefinition( &ccpf2->InputClassDef, count, 46455569331642446be05292e3e1f8a51218827168cdclaireho input_offset, base_offset, 46465569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 46475569331642446be05292e3e1f8a51218827168cdclaireho goto Fail4; 46485569331642446be05292e3e1f8a51218827168cdclaireho if ( ( error = _HB_OPEN_Load_EmptyOrClassDefinition( &ccpf2->LookaheadClassDef, 65535, 46495569331642446be05292e3e1f8a51218827168cdclaireho lookahead_offset, base_offset, 46505569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 46515569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 46525569331642446be05292e3e1f8a51218827168cdclaireho 46535569331642446be05292e3e1f8a51218827168cdclaireho ccpf2->ChainPosClassSet = NULL; 46545569331642446be05292e3e1f8a51218827168cdclaireho ccpf2->MaxBacktrackLength = 0; 46555569331642446be05292e3e1f8a51218827168cdclaireho ccpf2->MaxInputLength = 0; 46565569331642446be05292e3e1f8a51218827168cdclaireho ccpf2->MaxLookaheadLength = 0; 46575569331642446be05292e3e1f8a51218827168cdclaireho 46585569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( ccpf2->ChainPosClassSet, count, HB_ChainPosClassSet ) ) 46595569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 46605569331642446be05292e3e1f8a51218827168cdclaireho 46615569331642446be05292e3e1f8a51218827168cdclaireho cpcs = ccpf2->ChainPosClassSet; 46625569331642446be05292e3e1f8a51218827168cdclaireho 46635569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 46645569331642446be05292e3e1f8a51218827168cdclaireho { 46655569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 46665569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 46675569331642446be05292e3e1f8a51218827168cdclaireho 46685569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 46695569331642446be05292e3e1f8a51218827168cdclaireho 46705569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 46715569331642446be05292e3e1f8a51218827168cdclaireho 46725569331642446be05292e3e1f8a51218827168cdclaireho if ( new_offset != base_offset ) /* not a NULL offset */ 46735569331642446be05292e3e1f8a51218827168cdclaireho { 46745569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 46755569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 46765569331642446be05292e3e1f8a51218827168cdclaireho ( error = Load_ChainPosClassSet( ccpf2, &cpcs[n], 46775569331642446be05292e3e1f8a51218827168cdclaireho stream ) ) != HB_Err_Ok ) 46785569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 46795569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 46805569331642446be05292e3e1f8a51218827168cdclaireho } 46815569331642446be05292e3e1f8a51218827168cdclaireho else 46825569331642446be05292e3e1f8a51218827168cdclaireho { 46835569331642446be05292e3e1f8a51218827168cdclaireho /* we create a ChainPosClassSet table with no entries */ 46845569331642446be05292e3e1f8a51218827168cdclaireho 46855569331642446be05292e3e1f8a51218827168cdclaireho ccpf2->ChainPosClassSet[n].ChainPosClassRuleCount = 0; 46865569331642446be05292e3e1f8a51218827168cdclaireho ccpf2->ChainPosClassSet[n].ChainPosClassRule = NULL; 46875569331642446be05292e3e1f8a51218827168cdclaireho } 46885569331642446be05292e3e1f8a51218827168cdclaireho } 46895569331642446be05292e3e1f8a51218827168cdclaireho 46905569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 46915569331642446be05292e3e1f8a51218827168cdclaireho 46925569331642446be05292e3e1f8a51218827168cdclairehoFail1: 46935569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < n; m++ ) 46945569331642446be05292e3e1f8a51218827168cdclaireho Free_ChainPosClassSet( &cpcs[m] ); 46955569331642446be05292e3e1f8a51218827168cdclaireho 46965569331642446be05292e3e1f8a51218827168cdclaireho FREE( cpcs ); 46975569331642446be05292e3e1f8a51218827168cdclaireho 46985569331642446be05292e3e1f8a51218827168cdclairehoFail2: 46995569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_ClassDefinition( &ccpf2->LookaheadClassDef ); 47005569331642446be05292e3e1f8a51218827168cdclaireho 47015569331642446be05292e3e1f8a51218827168cdclairehoFail3: 47025569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_ClassDefinition( &ccpf2->InputClassDef ); 47035569331642446be05292e3e1f8a51218827168cdclaireho 47045569331642446be05292e3e1f8a51218827168cdclairehoFail4: 47055569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_ClassDefinition( &ccpf2->BacktrackClassDef ); 47065569331642446be05292e3e1f8a51218827168cdclaireho 47075569331642446be05292e3e1f8a51218827168cdclairehoFail5: 47085569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &ccpf2->Coverage ); 47095569331642446be05292e3e1f8a51218827168cdclaireho return error; 47105569331642446be05292e3e1f8a51218827168cdclaireho} 47115569331642446be05292e3e1f8a51218827168cdclaireho 47125569331642446be05292e3e1f8a51218827168cdclaireho 47135569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_ChainContextPos2( HB_ChainContextPosFormat2* ccpf2 ) 47145569331642446be05292e3e1f8a51218827168cdclaireho{ 47155569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 47165569331642446be05292e3e1f8a51218827168cdclaireho 47175569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainPosClassSet* cpcs; 47185569331642446be05292e3e1f8a51218827168cdclaireho 47195569331642446be05292e3e1f8a51218827168cdclaireho 47205569331642446be05292e3e1f8a51218827168cdclaireho if ( ccpf2->ChainPosClassSet ) 47215569331642446be05292e3e1f8a51218827168cdclaireho { 47225569331642446be05292e3e1f8a51218827168cdclaireho count = ccpf2->ChainPosClassSetCount; 47235569331642446be05292e3e1f8a51218827168cdclaireho cpcs = ccpf2->ChainPosClassSet; 47245569331642446be05292e3e1f8a51218827168cdclaireho 47255569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 47265569331642446be05292e3e1f8a51218827168cdclaireho Free_ChainPosClassSet( &cpcs[n] ); 47275569331642446be05292e3e1f8a51218827168cdclaireho 47285569331642446be05292e3e1f8a51218827168cdclaireho FREE( cpcs ); 47295569331642446be05292e3e1f8a51218827168cdclaireho } 47305569331642446be05292e3e1f8a51218827168cdclaireho 47315569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_ClassDefinition( &ccpf2->LookaheadClassDef ); 47325569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_ClassDefinition( &ccpf2->InputClassDef ); 47335569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_ClassDefinition( &ccpf2->BacktrackClassDef ); 47345569331642446be05292e3e1f8a51218827168cdclaireho 47355569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &ccpf2->Coverage ); 47365569331642446be05292e3e1f8a51218827168cdclaireho} 47375569331642446be05292e3e1f8a51218827168cdclaireho 47385569331642446be05292e3e1f8a51218827168cdclaireho 47395569331642446be05292e3e1f8a51218827168cdclaireho/* ChainContextPosFormat3 */ 47405569331642446be05292e3e1f8a51218827168cdclaireho 47415569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_ChainContextPos3( HB_ChainContextPosFormat3* ccpf3, 47425569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 47435569331642446be05292e3e1f8a51218827168cdclaireho{ 47445569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 47455569331642446be05292e3e1f8a51218827168cdclaireho 47465569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, nb, ni, nl, m, count; 47475569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort backtrack_count, input_count, lookahead_count; 47485569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt cur_offset, new_offset, base_offset; 47495569331642446be05292e3e1f8a51218827168cdclaireho 47505569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage* b; 47515569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage* i; 47525569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage* l; 47535569331642446be05292e3e1f8a51218827168cdclaireho HB_PosLookupRecord* plr; 47545569331642446be05292e3e1f8a51218827168cdclaireho 47555569331642446be05292e3e1f8a51218827168cdclaireho 47565569331642446be05292e3e1f8a51218827168cdclaireho base_offset = FILE_Pos() - 2L; 47575569331642446be05292e3e1f8a51218827168cdclaireho 47585569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 47595569331642446be05292e3e1f8a51218827168cdclaireho return error; 47605569331642446be05292e3e1f8a51218827168cdclaireho 47615569331642446be05292e3e1f8a51218827168cdclaireho ccpf3->BacktrackGlyphCount = GET_UShort(); 47625569331642446be05292e3e1f8a51218827168cdclaireho 47635569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 47645569331642446be05292e3e1f8a51218827168cdclaireho 47655569331642446be05292e3e1f8a51218827168cdclaireho ccpf3->BacktrackCoverage = NULL; 47665569331642446be05292e3e1f8a51218827168cdclaireho 47675569331642446be05292e3e1f8a51218827168cdclaireho backtrack_count = ccpf3->BacktrackGlyphCount; 47685569331642446be05292e3e1f8a51218827168cdclaireho 47695569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( ccpf3->BacktrackCoverage, backtrack_count, 47705569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage ) ) 47715569331642446be05292e3e1f8a51218827168cdclaireho return error; 47725569331642446be05292e3e1f8a51218827168cdclaireho 47735569331642446be05292e3e1f8a51218827168cdclaireho b = ccpf3->BacktrackCoverage; 47745569331642446be05292e3e1f8a51218827168cdclaireho 47755569331642446be05292e3e1f8a51218827168cdclaireho for ( nb = 0; nb < backtrack_count; nb++ ) 47765569331642446be05292e3e1f8a51218827168cdclaireho { 47775569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 47785569331642446be05292e3e1f8a51218827168cdclaireho goto Fail4; 47795569331642446be05292e3e1f8a51218827168cdclaireho 47805569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 47815569331642446be05292e3e1f8a51218827168cdclaireho 47825569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 47835569331642446be05292e3e1f8a51218827168cdclaireho 47845569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 47855569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 47865569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &b[nb], stream ) ) != HB_Err_Ok ) 47875569331642446be05292e3e1f8a51218827168cdclaireho goto Fail4; 47885569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 47895569331642446be05292e3e1f8a51218827168cdclaireho } 47905569331642446be05292e3e1f8a51218827168cdclaireho 47915569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 47925569331642446be05292e3e1f8a51218827168cdclaireho goto Fail4; 47935569331642446be05292e3e1f8a51218827168cdclaireho 47945569331642446be05292e3e1f8a51218827168cdclaireho ccpf3->InputGlyphCount = GET_UShort(); 47955569331642446be05292e3e1f8a51218827168cdclaireho 47965569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 47975569331642446be05292e3e1f8a51218827168cdclaireho 47985569331642446be05292e3e1f8a51218827168cdclaireho ccpf3->InputCoverage = NULL; 47995569331642446be05292e3e1f8a51218827168cdclaireho 48005569331642446be05292e3e1f8a51218827168cdclaireho input_count = ccpf3->InputGlyphCount; 48015569331642446be05292e3e1f8a51218827168cdclaireho 48025569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( ccpf3->InputCoverage, input_count, HB_Coverage ) ) 48035569331642446be05292e3e1f8a51218827168cdclaireho goto Fail4; 48045569331642446be05292e3e1f8a51218827168cdclaireho 48055569331642446be05292e3e1f8a51218827168cdclaireho i = ccpf3->InputCoverage; 48065569331642446be05292e3e1f8a51218827168cdclaireho 48075569331642446be05292e3e1f8a51218827168cdclaireho for ( ni = 0; ni < input_count; ni++ ) 48085569331642446be05292e3e1f8a51218827168cdclaireho { 48095569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 48105569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 48115569331642446be05292e3e1f8a51218827168cdclaireho 48125569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 48135569331642446be05292e3e1f8a51218827168cdclaireho 48145569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 48155569331642446be05292e3e1f8a51218827168cdclaireho 48165569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 48175569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 48185569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &i[ni], stream ) ) != HB_Err_Ok ) 48195569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 48205569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 48215569331642446be05292e3e1f8a51218827168cdclaireho } 48225569331642446be05292e3e1f8a51218827168cdclaireho 48235569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 48245569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 48255569331642446be05292e3e1f8a51218827168cdclaireho 48265569331642446be05292e3e1f8a51218827168cdclaireho ccpf3->LookaheadGlyphCount = GET_UShort(); 48275569331642446be05292e3e1f8a51218827168cdclaireho 48285569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 48295569331642446be05292e3e1f8a51218827168cdclaireho 48305569331642446be05292e3e1f8a51218827168cdclaireho ccpf3->LookaheadCoverage = NULL; 48315569331642446be05292e3e1f8a51218827168cdclaireho 48325569331642446be05292e3e1f8a51218827168cdclaireho lookahead_count = ccpf3->LookaheadGlyphCount; 48335569331642446be05292e3e1f8a51218827168cdclaireho 48345569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( ccpf3->LookaheadCoverage, lookahead_count, 48355569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage ) ) 48365569331642446be05292e3e1f8a51218827168cdclaireho goto Fail3; 48375569331642446be05292e3e1f8a51218827168cdclaireho 48385569331642446be05292e3e1f8a51218827168cdclaireho l = ccpf3->LookaheadCoverage; 48395569331642446be05292e3e1f8a51218827168cdclaireho 48405569331642446be05292e3e1f8a51218827168cdclaireho for ( nl = 0; nl < lookahead_count; nl++ ) 48415569331642446be05292e3e1f8a51218827168cdclaireho { 48425569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 48435569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 48445569331642446be05292e3e1f8a51218827168cdclaireho 48455569331642446be05292e3e1f8a51218827168cdclaireho new_offset = GET_UShort() + base_offset; 48465569331642446be05292e3e1f8a51218827168cdclaireho 48475569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 48485569331642446be05292e3e1f8a51218827168cdclaireho 48495569331642446be05292e3e1f8a51218827168cdclaireho cur_offset = FILE_Pos(); 48505569331642446be05292e3e1f8a51218827168cdclaireho if ( FILE_Seek( new_offset ) || 48515569331642446be05292e3e1f8a51218827168cdclaireho ( error = _HB_OPEN_Load_Coverage( &l[nl], stream ) ) != HB_Err_Ok ) 48525569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 48535569331642446be05292e3e1f8a51218827168cdclaireho (void)FILE_Seek( cur_offset ); 48545569331642446be05292e3e1f8a51218827168cdclaireho } 48555569331642446be05292e3e1f8a51218827168cdclaireho 48565569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 48575569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 48585569331642446be05292e3e1f8a51218827168cdclaireho 48595569331642446be05292e3e1f8a51218827168cdclaireho ccpf3->PosCount = GET_UShort(); 48605569331642446be05292e3e1f8a51218827168cdclaireho 48615569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 48625569331642446be05292e3e1f8a51218827168cdclaireho 48635569331642446be05292e3e1f8a51218827168cdclaireho ccpf3->PosLookupRecord = NULL; 48645569331642446be05292e3e1f8a51218827168cdclaireho 48655569331642446be05292e3e1f8a51218827168cdclaireho count = ccpf3->PosCount; 48665569331642446be05292e3e1f8a51218827168cdclaireho 48675569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( ccpf3->PosLookupRecord, count, HB_PosLookupRecord ) ) 48685569331642446be05292e3e1f8a51218827168cdclaireho goto Fail2; 48695569331642446be05292e3e1f8a51218827168cdclaireho 48705569331642446be05292e3e1f8a51218827168cdclaireho plr = ccpf3->PosLookupRecord; 48715569331642446be05292e3e1f8a51218827168cdclaireho 48725569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( count * 4L ) ) 48735569331642446be05292e3e1f8a51218827168cdclaireho goto Fail1; 48745569331642446be05292e3e1f8a51218827168cdclaireho 48755569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 48765569331642446be05292e3e1f8a51218827168cdclaireho { 48775569331642446be05292e3e1f8a51218827168cdclaireho plr[n].SequenceIndex = GET_UShort(); 48785569331642446be05292e3e1f8a51218827168cdclaireho plr[n].LookupListIndex = GET_UShort(); 48795569331642446be05292e3e1f8a51218827168cdclaireho } 48805569331642446be05292e3e1f8a51218827168cdclaireho 48815569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 48825569331642446be05292e3e1f8a51218827168cdclaireho 48835569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 48845569331642446be05292e3e1f8a51218827168cdclaireho 48855569331642446be05292e3e1f8a51218827168cdclairehoFail1: 48865569331642446be05292e3e1f8a51218827168cdclaireho FREE( plr ); 48875569331642446be05292e3e1f8a51218827168cdclaireho 48885569331642446be05292e3e1f8a51218827168cdclairehoFail2: 48895569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < nl; m++ ) 48905569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &l[m] ); 48915569331642446be05292e3e1f8a51218827168cdclaireho 48925569331642446be05292e3e1f8a51218827168cdclaireho FREE( l ); 48935569331642446be05292e3e1f8a51218827168cdclaireho 48945569331642446be05292e3e1f8a51218827168cdclairehoFail3: 48955569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < ni; m++ ) 48965569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &i[m] ); 48975569331642446be05292e3e1f8a51218827168cdclaireho 48985569331642446be05292e3e1f8a51218827168cdclaireho FREE( i ); 48995569331642446be05292e3e1f8a51218827168cdclaireho 49005569331642446be05292e3e1f8a51218827168cdclairehoFail4: 49015569331642446be05292e3e1f8a51218827168cdclaireho for ( m = 0; m < nb; m++ ) 49025569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &b[m] ); 49035569331642446be05292e3e1f8a51218827168cdclaireho 49045569331642446be05292e3e1f8a51218827168cdclaireho FREE( b ); 49055569331642446be05292e3e1f8a51218827168cdclaireho return error; 49065569331642446be05292e3e1f8a51218827168cdclaireho} 49075569331642446be05292e3e1f8a51218827168cdclaireho 49085569331642446be05292e3e1f8a51218827168cdclaireho 49095569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_ChainContextPos3( HB_ChainContextPosFormat3* ccpf3 ) 49105569331642446be05292e3e1f8a51218827168cdclaireho{ 49115569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n, count; 49125569331642446be05292e3e1f8a51218827168cdclaireho 49135569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage* c; 49145569331642446be05292e3e1f8a51218827168cdclaireho 49155569331642446be05292e3e1f8a51218827168cdclaireho 49165569331642446be05292e3e1f8a51218827168cdclaireho FREE( ccpf3->PosLookupRecord ); 49175569331642446be05292e3e1f8a51218827168cdclaireho 49185569331642446be05292e3e1f8a51218827168cdclaireho if ( ccpf3->LookaheadCoverage ) 49195569331642446be05292e3e1f8a51218827168cdclaireho { 49205569331642446be05292e3e1f8a51218827168cdclaireho count = ccpf3->LookaheadGlyphCount; 49215569331642446be05292e3e1f8a51218827168cdclaireho c = ccpf3->LookaheadCoverage; 49225569331642446be05292e3e1f8a51218827168cdclaireho 49235569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 49245569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &c[n] ); 49255569331642446be05292e3e1f8a51218827168cdclaireho 49265569331642446be05292e3e1f8a51218827168cdclaireho FREE( c ); 49275569331642446be05292e3e1f8a51218827168cdclaireho } 49285569331642446be05292e3e1f8a51218827168cdclaireho 49295569331642446be05292e3e1f8a51218827168cdclaireho if ( ccpf3->InputCoverage ) 49305569331642446be05292e3e1f8a51218827168cdclaireho { 49315569331642446be05292e3e1f8a51218827168cdclaireho count = ccpf3->InputGlyphCount; 49325569331642446be05292e3e1f8a51218827168cdclaireho c = ccpf3->InputCoverage; 49335569331642446be05292e3e1f8a51218827168cdclaireho 49345569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 49355569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &c[n] ); 49365569331642446be05292e3e1f8a51218827168cdclaireho 49375569331642446be05292e3e1f8a51218827168cdclaireho FREE( c ); 49385569331642446be05292e3e1f8a51218827168cdclaireho } 49395569331642446be05292e3e1f8a51218827168cdclaireho 49405569331642446be05292e3e1f8a51218827168cdclaireho if ( ccpf3->BacktrackCoverage ) 49415569331642446be05292e3e1f8a51218827168cdclaireho { 49425569331642446be05292e3e1f8a51218827168cdclaireho count = ccpf3->BacktrackGlyphCount; 49435569331642446be05292e3e1f8a51218827168cdclaireho c = ccpf3->BacktrackCoverage; 49445569331642446be05292e3e1f8a51218827168cdclaireho 49455569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < count; n++ ) 49465569331642446be05292e3e1f8a51218827168cdclaireho _HB_OPEN_Free_Coverage( &c[n] ); 49475569331642446be05292e3e1f8a51218827168cdclaireho 49485569331642446be05292e3e1f8a51218827168cdclaireho FREE( c ); 49495569331642446be05292e3e1f8a51218827168cdclaireho } 49505569331642446be05292e3e1f8a51218827168cdclaireho} 49515569331642446be05292e3e1f8a51218827168cdclaireho 49525569331642446be05292e3e1f8a51218827168cdclaireho 49535569331642446be05292e3e1f8a51218827168cdclaireho/* ChainContextPos */ 49545569331642446be05292e3e1f8a51218827168cdclaireho 49555569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Load_ChainContextPos( HB_GPOS_SubTable* st, 49565569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream ) 49575569331642446be05292e3e1f8a51218827168cdclaireho{ 49585569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 49595569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainContextPos* ccp = &st->chain; 49605569331642446be05292e3e1f8a51218827168cdclaireho 49615569331642446be05292e3e1f8a51218827168cdclaireho 49625569331642446be05292e3e1f8a51218827168cdclaireho if ( ACCESS_Frame( 2L ) ) 49635569331642446be05292e3e1f8a51218827168cdclaireho return error; 49645569331642446be05292e3e1f8a51218827168cdclaireho 49655569331642446be05292e3e1f8a51218827168cdclaireho ccp->PosFormat = GET_UShort(); 49665569331642446be05292e3e1f8a51218827168cdclaireho 49675569331642446be05292e3e1f8a51218827168cdclaireho FORGET_Frame(); 49685569331642446be05292e3e1f8a51218827168cdclaireho 49695569331642446be05292e3e1f8a51218827168cdclaireho switch ( ccp->PosFormat ) 49705569331642446be05292e3e1f8a51218827168cdclaireho { 49715569331642446be05292e3e1f8a51218827168cdclaireho case 1: 49725569331642446be05292e3e1f8a51218827168cdclaireho return Load_ChainContextPos1( &ccp->ccpf.ccpf1, stream ); 49735569331642446be05292e3e1f8a51218827168cdclaireho 49745569331642446be05292e3e1f8a51218827168cdclaireho case 2: 49755569331642446be05292e3e1f8a51218827168cdclaireho return Load_ChainContextPos2( &ccp->ccpf.ccpf2, stream ); 49765569331642446be05292e3e1f8a51218827168cdclaireho 49775569331642446be05292e3e1f8a51218827168cdclaireho case 3: 49785569331642446be05292e3e1f8a51218827168cdclaireho return Load_ChainContextPos3( &ccp->ccpf.ccpf3, stream ); 49795569331642446be05292e3e1f8a51218827168cdclaireho 49805569331642446be05292e3e1f8a51218827168cdclaireho default: 49815569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable_Format); 49825569331642446be05292e3e1f8a51218827168cdclaireho } 49835569331642446be05292e3e1f8a51218827168cdclaireho 49845569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; /* never reached */ 49855569331642446be05292e3e1f8a51218827168cdclaireho} 49865569331642446be05292e3e1f8a51218827168cdclaireho 49875569331642446be05292e3e1f8a51218827168cdclaireho 49885569331642446be05292e3e1f8a51218827168cdclairehostatic void Free_ChainContextPos( HB_GPOS_SubTable* st ) 49895569331642446be05292e3e1f8a51218827168cdclaireho{ 49905569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainContextPos* ccp = &st->chain; 49915569331642446be05292e3e1f8a51218827168cdclaireho 49925569331642446be05292e3e1f8a51218827168cdclaireho switch ( ccp->PosFormat ) 49935569331642446be05292e3e1f8a51218827168cdclaireho { 49945569331642446be05292e3e1f8a51218827168cdclaireho case 1: Free_ChainContextPos1( &ccp->ccpf.ccpf1 ); break; 49955569331642446be05292e3e1f8a51218827168cdclaireho case 2: Free_ChainContextPos2( &ccp->ccpf.ccpf2 ); break; 49965569331642446be05292e3e1f8a51218827168cdclaireho case 3: Free_ChainContextPos3( &ccp->ccpf.ccpf3 ); break; 49975569331642446be05292e3e1f8a51218827168cdclaireho default: break; 49985569331642446be05292e3e1f8a51218827168cdclaireho } 49995569331642446be05292e3e1f8a51218827168cdclaireho} 50005569331642446be05292e3e1f8a51218827168cdclaireho 50015569331642446be05292e3e1f8a51218827168cdclaireho 50025569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Lookup_ChainContextPos1( 50035569331642446be05292e3e1f8a51218827168cdclaireho GPOS_Instance* gpi, 50045569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainContextPosFormat1* ccpf1, 50055569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 50065569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort flags, 50075569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 50085569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 50095569331642446be05292e3e1f8a51218827168cdclaireho{ 50105569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort index, property; 50115569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort i, j, k, num_cpr; 50125569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort bgc, igc, lgc; 50135569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 50145569331642446be05292e3e1f8a51218827168cdclaireho HB_GPOSHeader* gpos = gpi->gpos; 50155569331642446be05292e3e1f8a51218827168cdclaireho 50165569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainPosRule* cpr; 50175569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainPosRule curr_cpr; 50185569331642446be05292e3e1f8a51218827168cdclaireho HB_GDEFHeader* gdef; 50195569331642446be05292e3e1f8a51218827168cdclaireho 50205569331642446be05292e3e1f8a51218827168cdclaireho 50215569331642446be05292e3e1f8a51218827168cdclaireho gdef = gpos->gdef; 50225569331642446be05292e3e1f8a51218827168cdclaireho 50235569331642446be05292e3e1f8a51218827168cdclaireho if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) 50245569331642446be05292e3e1f8a51218827168cdclaireho return error; 50255569331642446be05292e3e1f8a51218827168cdclaireho 50265569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &ccpf1->Coverage, IN_CURGLYPH(), &index ); 50275569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 50285569331642446be05292e3e1f8a51218827168cdclaireho return error; 50295569331642446be05292e3e1f8a51218827168cdclaireho 50305569331642446be05292e3e1f8a51218827168cdclaireho cpr = ccpf1->ChainPosRuleSet[index].ChainPosRule; 50315569331642446be05292e3e1f8a51218827168cdclaireho num_cpr = ccpf1->ChainPosRuleSet[index].ChainPosRuleCount; 50325569331642446be05292e3e1f8a51218827168cdclaireho 50335569331642446be05292e3e1f8a51218827168cdclaireho for ( k = 0; k < num_cpr; k++ ) 50345569331642446be05292e3e1f8a51218827168cdclaireho { 50355569331642446be05292e3e1f8a51218827168cdclaireho curr_cpr = cpr[k]; 50365569331642446be05292e3e1f8a51218827168cdclaireho bgc = curr_cpr.BacktrackGlyphCount; 50375569331642446be05292e3e1f8a51218827168cdclaireho igc = curr_cpr.InputGlyphCount; 50385569331642446be05292e3e1f8a51218827168cdclaireho lgc = curr_cpr.LookaheadGlyphCount; 50395569331642446be05292e3e1f8a51218827168cdclaireho 50405569331642446be05292e3e1f8a51218827168cdclaireho if ( context_length != 0xFFFF && context_length < igc ) 50415569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainposrule; 50425569331642446be05292e3e1f8a51218827168cdclaireho 50435569331642446be05292e3e1f8a51218827168cdclaireho /* check whether context is too long; it is a first guess only */ 50445569331642446be05292e3e1f8a51218827168cdclaireho 50455569331642446be05292e3e1f8a51218827168cdclaireho if ( bgc > buffer->in_pos || buffer->in_pos + igc + lgc > buffer->in_length ) 50465569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainposrule; 50475569331642446be05292e3e1f8a51218827168cdclaireho 50485569331642446be05292e3e1f8a51218827168cdclaireho if ( bgc ) 50495569331642446be05292e3e1f8a51218827168cdclaireho { 50505569331642446be05292e3e1f8a51218827168cdclaireho /* Since we don't know in advance the number of glyphs to inspect, 50515569331642446be05292e3e1f8a51218827168cdclaireho we search backwards for matches in the backtrack glyph array */ 50525569331642446be05292e3e1f8a51218827168cdclaireho 50535569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 0, j = buffer->in_pos - 1; i < bgc; i++, j-- ) 50545569331642446be05292e3e1f8a51218827168cdclaireho { 50555569331642446be05292e3e1f8a51218827168cdclaireho while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) 50565569331642446be05292e3e1f8a51218827168cdclaireho { 50575569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 50585569331642446be05292e3e1f8a51218827168cdclaireho return error; 50595569331642446be05292e3e1f8a51218827168cdclaireho 50605569331642446be05292e3e1f8a51218827168cdclaireho if ( j + 1 == bgc - i ) 50615569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainposrule; 50625569331642446be05292e3e1f8a51218827168cdclaireho j--; 50635569331642446be05292e3e1f8a51218827168cdclaireho } 50645569331642446be05292e3e1f8a51218827168cdclaireho 50655569331642446be05292e3e1f8a51218827168cdclaireho /* In OpenType 1.3, it is undefined whether the offsets of 50665569331642446be05292e3e1f8a51218827168cdclaireho backtrack glyphs is in logical order or not. Version 1.4 50675569331642446be05292e3e1f8a51218827168cdclaireho will clarify this: 50685569331642446be05292e3e1f8a51218827168cdclaireho 50695569331642446be05292e3e1f8a51218827168cdclaireho Logical order - a b c d e f g h i j 50705569331642446be05292e3e1f8a51218827168cdclaireho i 50715569331642446be05292e3e1f8a51218827168cdclaireho Input offsets - 0 1 50725569331642446be05292e3e1f8a51218827168cdclaireho Backtrack offsets - 3 2 1 0 50735569331642446be05292e3e1f8a51218827168cdclaireho Lookahead offsets - 0 1 2 3 */ 50745569331642446be05292e3e1f8a51218827168cdclaireho 50755569331642446be05292e3e1f8a51218827168cdclaireho if ( IN_GLYPH( j ) != curr_cpr.Backtrack[i] ) 50765569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainposrule; 50775569331642446be05292e3e1f8a51218827168cdclaireho } 50785569331642446be05292e3e1f8a51218827168cdclaireho } 50795569331642446be05292e3e1f8a51218827168cdclaireho 50805569331642446be05292e3e1f8a51218827168cdclaireho /* Start at 1 because [0] is implied */ 50815569331642446be05292e3e1f8a51218827168cdclaireho 50825569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 1, j = buffer->in_pos + 1; i < igc; i++, j++ ) 50835569331642446be05292e3e1f8a51218827168cdclaireho { 50845569331642446be05292e3e1f8a51218827168cdclaireho while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) 50855569331642446be05292e3e1f8a51218827168cdclaireho { 50865569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 50875569331642446be05292e3e1f8a51218827168cdclaireho return error; 50885569331642446be05292e3e1f8a51218827168cdclaireho 50895569331642446be05292e3e1f8a51218827168cdclaireho if ( j + igc - i + lgc == (HB_Int)buffer->in_length ) 50905569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainposrule; 50915569331642446be05292e3e1f8a51218827168cdclaireho j++; 50925569331642446be05292e3e1f8a51218827168cdclaireho } 50935569331642446be05292e3e1f8a51218827168cdclaireho 50945569331642446be05292e3e1f8a51218827168cdclaireho if ( IN_GLYPH( j ) != curr_cpr.Input[i - 1] ) 50955569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainposrule; 50965569331642446be05292e3e1f8a51218827168cdclaireho } 50975569331642446be05292e3e1f8a51218827168cdclaireho 50985569331642446be05292e3e1f8a51218827168cdclaireho /* we are starting to check for lookahead glyphs right after the 50995569331642446be05292e3e1f8a51218827168cdclaireho last context glyph */ 51005569331642446be05292e3e1f8a51218827168cdclaireho 51015569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 0; i < lgc; i++, j++ ) 51025569331642446be05292e3e1f8a51218827168cdclaireho { 51035569331642446be05292e3e1f8a51218827168cdclaireho while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) 51045569331642446be05292e3e1f8a51218827168cdclaireho { 51055569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 51065569331642446be05292e3e1f8a51218827168cdclaireho return error; 51075569331642446be05292e3e1f8a51218827168cdclaireho 51085569331642446be05292e3e1f8a51218827168cdclaireho if ( j + lgc - i == (HB_Int)buffer->in_length ) 51095569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainposrule; 51105569331642446be05292e3e1f8a51218827168cdclaireho j++; 51115569331642446be05292e3e1f8a51218827168cdclaireho } 51125569331642446be05292e3e1f8a51218827168cdclaireho 51135569331642446be05292e3e1f8a51218827168cdclaireho if ( IN_GLYPH( j ) != curr_cpr.Lookahead[i] ) 51145569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainposrule; 51155569331642446be05292e3e1f8a51218827168cdclaireho } 51165569331642446be05292e3e1f8a51218827168cdclaireho 51175569331642446be05292e3e1f8a51218827168cdclaireho return Do_ContextPos( gpi, igc, 51185569331642446be05292e3e1f8a51218827168cdclaireho curr_cpr.PosCount, 51195569331642446be05292e3e1f8a51218827168cdclaireho curr_cpr.PosLookupRecord, 51205569331642446be05292e3e1f8a51218827168cdclaireho buffer, 51215569331642446be05292e3e1f8a51218827168cdclaireho nesting_level ); 51225569331642446be05292e3e1f8a51218827168cdclaireho 51235569331642446be05292e3e1f8a51218827168cdclaireho next_chainposrule: 51245569331642446be05292e3e1f8a51218827168cdclaireho ; 51255569331642446be05292e3e1f8a51218827168cdclaireho } 51265569331642446be05292e3e1f8a51218827168cdclaireho 51275569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 51285569331642446be05292e3e1f8a51218827168cdclaireho} 51295569331642446be05292e3e1f8a51218827168cdclaireho 51305569331642446be05292e3e1f8a51218827168cdclaireho 51315569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Lookup_ChainContextPos2( 51325569331642446be05292e3e1f8a51218827168cdclaireho GPOS_Instance* gpi, 51335569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainContextPosFormat2* ccpf2, 51345569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 51355569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort flags, 51365569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 51375569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 51385569331642446be05292e3e1f8a51218827168cdclaireho{ 51395569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort index, property; 51405569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 51415569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort i, j, k; 51425569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort bgc, igc, lgc; 51435569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort known_backtrack_classes, 51445569331642446be05292e3e1f8a51218827168cdclaireho known_input_classes, 51455569331642446be05292e3e1f8a51218827168cdclaireho known_lookahead_classes; 51465569331642446be05292e3e1f8a51218827168cdclaireho 51475569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* backtrack_classes; 51485569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* input_classes; 51495569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* lookahead_classes; 51505569331642446be05292e3e1f8a51218827168cdclaireho 51515569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* bc; 51525569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* ic; 51535569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* lc; 51545569331642446be05292e3e1f8a51218827168cdclaireho HB_GPOSHeader* gpos = gpi->gpos; 51555569331642446be05292e3e1f8a51218827168cdclaireho 51565569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainPosClassSet* cpcs; 51575569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainPosClassRule cpcr; 51585569331642446be05292e3e1f8a51218827168cdclaireho HB_GDEFHeader* gdef; 51595569331642446be05292e3e1f8a51218827168cdclaireho 51605569331642446be05292e3e1f8a51218827168cdclaireho 51615569331642446be05292e3e1f8a51218827168cdclaireho gdef = gpos->gdef; 51625569331642446be05292e3e1f8a51218827168cdclaireho 51635569331642446be05292e3e1f8a51218827168cdclaireho if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) 51645569331642446be05292e3e1f8a51218827168cdclaireho return error; 51655569331642446be05292e3e1f8a51218827168cdclaireho 51665569331642446be05292e3e1f8a51218827168cdclaireho /* Note: The coverage table in format 2 doesn't give an index into 51675569331642446be05292e3e1f8a51218827168cdclaireho anything. It just lets us know whether or not we need to 51685569331642446be05292e3e1f8a51218827168cdclaireho do any lookup at all. */ 51695569331642446be05292e3e1f8a51218827168cdclaireho 51705569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &ccpf2->Coverage, IN_CURGLYPH(), &index ); 51715569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 51725569331642446be05292e3e1f8a51218827168cdclaireho return error; 51735569331642446be05292e3e1f8a51218827168cdclaireho 5174d124f9692dc8dad8f5f77c293fe6d4ec1a0c02eaRaph Levien if (ccpf2->MaxInputLength < 1) 5175d124f9692dc8dad8f5f77c293fe6d4ec1a0c02eaRaph Levien return HB_Err_Not_Covered; 5176d124f9692dc8dad8f5f77c293fe6d4ec1a0c02eaRaph Levien 51775569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( backtrack_classes, ccpf2->MaxBacktrackLength, HB_UShort ) ) 51785569331642446be05292e3e1f8a51218827168cdclaireho return error; 51795569331642446be05292e3e1f8a51218827168cdclaireho known_backtrack_classes = 0; 51805569331642446be05292e3e1f8a51218827168cdclaireho 51815569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( input_classes, ccpf2->MaxInputLength, HB_UShort ) ) 51825569331642446be05292e3e1f8a51218827168cdclaireho goto End3; 51835569331642446be05292e3e1f8a51218827168cdclaireho known_input_classes = 1; 51845569331642446be05292e3e1f8a51218827168cdclaireho 51855569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( lookahead_classes, ccpf2->MaxLookaheadLength, HB_UShort ) ) 51865569331642446be05292e3e1f8a51218827168cdclaireho goto End2; 51875569331642446be05292e3e1f8a51218827168cdclaireho known_lookahead_classes = 0; 51885569331642446be05292e3e1f8a51218827168cdclaireho 51895569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Get_Class( &ccpf2->InputClassDef, IN_CURGLYPH(), 51905569331642446be05292e3e1f8a51218827168cdclaireho &input_classes[0], NULL ); 51915569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 51925569331642446be05292e3e1f8a51218827168cdclaireho goto End1; 51935569331642446be05292e3e1f8a51218827168cdclaireho 51945569331642446be05292e3e1f8a51218827168cdclaireho cpcs = &ccpf2->ChainPosClassSet[input_classes[0]]; 51955569331642446be05292e3e1f8a51218827168cdclaireho if ( !cpcs ) 51965569331642446be05292e3e1f8a51218827168cdclaireho { 51975569331642446be05292e3e1f8a51218827168cdclaireho error = ERR(HB_Err_Invalid_SubTable); 51985569331642446be05292e3e1f8a51218827168cdclaireho goto End1; 51995569331642446be05292e3e1f8a51218827168cdclaireho } 52005569331642446be05292e3e1f8a51218827168cdclaireho 52015569331642446be05292e3e1f8a51218827168cdclaireho for ( k = 0; k < cpcs->ChainPosClassRuleCount; k++ ) 52025569331642446be05292e3e1f8a51218827168cdclaireho { 52035569331642446be05292e3e1f8a51218827168cdclaireho cpcr = cpcs->ChainPosClassRule[k]; 52045569331642446be05292e3e1f8a51218827168cdclaireho bgc = cpcr.BacktrackGlyphCount; 52055569331642446be05292e3e1f8a51218827168cdclaireho igc = cpcr.InputGlyphCount; 52065569331642446be05292e3e1f8a51218827168cdclaireho lgc = cpcr.LookaheadGlyphCount; 52075569331642446be05292e3e1f8a51218827168cdclaireho 52085569331642446be05292e3e1f8a51218827168cdclaireho if ( context_length != 0xFFFF && context_length < igc ) 52095569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainposclassrule; 52105569331642446be05292e3e1f8a51218827168cdclaireho 52115569331642446be05292e3e1f8a51218827168cdclaireho /* check whether context is too long; it is a first guess only */ 52125569331642446be05292e3e1f8a51218827168cdclaireho 52135569331642446be05292e3e1f8a51218827168cdclaireho if ( bgc > buffer->in_pos || buffer->in_pos + igc + lgc > buffer->in_length ) 52145569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainposclassrule; 52155569331642446be05292e3e1f8a51218827168cdclaireho 52165569331642446be05292e3e1f8a51218827168cdclaireho if ( bgc ) 52175569331642446be05292e3e1f8a51218827168cdclaireho { 52185569331642446be05292e3e1f8a51218827168cdclaireho /* Since we don't know in advance the number of glyphs to inspect, 52195569331642446be05292e3e1f8a51218827168cdclaireho we search backwards for matches in the backtrack glyph array. 52205569331642446be05292e3e1f8a51218827168cdclaireho Note that `known_backtrack_classes' starts at index 0. */ 52215569331642446be05292e3e1f8a51218827168cdclaireho 52225569331642446be05292e3e1f8a51218827168cdclaireho bc = cpcr.Backtrack; 52235569331642446be05292e3e1f8a51218827168cdclaireho 52245569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 0, j = buffer->in_pos - 1; i < bgc; i++, j-- ) 52255569331642446be05292e3e1f8a51218827168cdclaireho { 52265569331642446be05292e3e1f8a51218827168cdclaireho while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) 52275569331642446be05292e3e1f8a51218827168cdclaireho { 52285569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 52295569331642446be05292e3e1f8a51218827168cdclaireho goto End1; 52305569331642446be05292e3e1f8a51218827168cdclaireho 52315569331642446be05292e3e1f8a51218827168cdclaireho if ( j + 1 == bgc - i ) 52325569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainposclassrule; 52335569331642446be05292e3e1f8a51218827168cdclaireho j++; 52345569331642446be05292e3e1f8a51218827168cdclaireho } 52355569331642446be05292e3e1f8a51218827168cdclaireho 52365569331642446be05292e3e1f8a51218827168cdclaireho if ( i >= known_backtrack_classes ) 52375569331642446be05292e3e1f8a51218827168cdclaireho { 52385569331642446be05292e3e1f8a51218827168cdclaireho /* Keeps us from having to do this for each rule */ 52395569331642446be05292e3e1f8a51218827168cdclaireho 52405569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Get_Class( &ccpf2->BacktrackClassDef, IN_GLYPH( j ), 52415569331642446be05292e3e1f8a51218827168cdclaireho &backtrack_classes[i], NULL ); 52425569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 52435569331642446be05292e3e1f8a51218827168cdclaireho goto End1; 52445569331642446be05292e3e1f8a51218827168cdclaireho known_backtrack_classes = i; 52455569331642446be05292e3e1f8a51218827168cdclaireho } 52465569331642446be05292e3e1f8a51218827168cdclaireho 52475569331642446be05292e3e1f8a51218827168cdclaireho if ( bc[i] != backtrack_classes[i] ) 52485569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainposclassrule; 52495569331642446be05292e3e1f8a51218827168cdclaireho } 52505569331642446be05292e3e1f8a51218827168cdclaireho } 52515569331642446be05292e3e1f8a51218827168cdclaireho 52525569331642446be05292e3e1f8a51218827168cdclaireho ic = cpcr.Input; 52535569331642446be05292e3e1f8a51218827168cdclaireho 52545569331642446be05292e3e1f8a51218827168cdclaireho /* Start at 1 because [0] is implied */ 52555569331642446be05292e3e1f8a51218827168cdclaireho 52565569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 1, j = buffer->in_pos + 1; i < igc; i++, j++ ) 52575569331642446be05292e3e1f8a51218827168cdclaireho { 52585569331642446be05292e3e1f8a51218827168cdclaireho while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) 52595569331642446be05292e3e1f8a51218827168cdclaireho { 52605569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 52615569331642446be05292e3e1f8a51218827168cdclaireho goto End1; 52625569331642446be05292e3e1f8a51218827168cdclaireho 52635569331642446be05292e3e1f8a51218827168cdclaireho if ( j + igc - i + lgc == (HB_Int)buffer->in_length ) 52645569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainposclassrule; 52655569331642446be05292e3e1f8a51218827168cdclaireho j++; 52665569331642446be05292e3e1f8a51218827168cdclaireho } 52675569331642446be05292e3e1f8a51218827168cdclaireho 52685569331642446be05292e3e1f8a51218827168cdclaireho if ( i >= known_input_classes ) 52695569331642446be05292e3e1f8a51218827168cdclaireho { 52705569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Get_Class( &ccpf2->InputClassDef, IN_GLYPH( j ), 52715569331642446be05292e3e1f8a51218827168cdclaireho &input_classes[i], NULL ); 52725569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 52735569331642446be05292e3e1f8a51218827168cdclaireho goto End1; 52745569331642446be05292e3e1f8a51218827168cdclaireho known_input_classes = i; 52755569331642446be05292e3e1f8a51218827168cdclaireho } 52765569331642446be05292e3e1f8a51218827168cdclaireho 52775569331642446be05292e3e1f8a51218827168cdclaireho if ( ic[i - 1] != input_classes[i] ) 52785569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainposclassrule; 52795569331642446be05292e3e1f8a51218827168cdclaireho } 52805569331642446be05292e3e1f8a51218827168cdclaireho 52815569331642446be05292e3e1f8a51218827168cdclaireho /* we are starting to check for lookahead glyphs right after the 52825569331642446be05292e3e1f8a51218827168cdclaireho last context glyph */ 52835569331642446be05292e3e1f8a51218827168cdclaireho 52845569331642446be05292e3e1f8a51218827168cdclaireho lc = cpcr.Lookahead; 52855569331642446be05292e3e1f8a51218827168cdclaireho 52865569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 0; i < lgc; i++, j++ ) 52875569331642446be05292e3e1f8a51218827168cdclaireho { 52885569331642446be05292e3e1f8a51218827168cdclaireho while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) 52895569331642446be05292e3e1f8a51218827168cdclaireho { 52905569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 52915569331642446be05292e3e1f8a51218827168cdclaireho goto End1; 52925569331642446be05292e3e1f8a51218827168cdclaireho 52935569331642446be05292e3e1f8a51218827168cdclaireho if ( j + lgc - i == (HB_Int)buffer->in_length ) 52945569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainposclassrule; 52955569331642446be05292e3e1f8a51218827168cdclaireho j++; 52965569331642446be05292e3e1f8a51218827168cdclaireho } 52975569331642446be05292e3e1f8a51218827168cdclaireho 52985569331642446be05292e3e1f8a51218827168cdclaireho if ( i >= known_lookahead_classes ) 52995569331642446be05292e3e1f8a51218827168cdclaireho { 53005569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Get_Class( &ccpf2->LookaheadClassDef, IN_GLYPH( j ), 53015569331642446be05292e3e1f8a51218827168cdclaireho &lookahead_classes[i], NULL ); 53025569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 53035569331642446be05292e3e1f8a51218827168cdclaireho goto End1; 53045569331642446be05292e3e1f8a51218827168cdclaireho known_lookahead_classes = i; 53055569331642446be05292e3e1f8a51218827168cdclaireho } 53065569331642446be05292e3e1f8a51218827168cdclaireho 53075569331642446be05292e3e1f8a51218827168cdclaireho if ( lc[i] != lookahead_classes[i] ) 53085569331642446be05292e3e1f8a51218827168cdclaireho goto next_chainposclassrule; 53095569331642446be05292e3e1f8a51218827168cdclaireho } 53105569331642446be05292e3e1f8a51218827168cdclaireho 53115569331642446be05292e3e1f8a51218827168cdclaireho error = Do_ContextPos( gpi, igc, 53125569331642446be05292e3e1f8a51218827168cdclaireho cpcr.PosCount, 53135569331642446be05292e3e1f8a51218827168cdclaireho cpcr.PosLookupRecord, 53145569331642446be05292e3e1f8a51218827168cdclaireho buffer, 53155569331642446be05292e3e1f8a51218827168cdclaireho nesting_level ); 53165569331642446be05292e3e1f8a51218827168cdclaireho goto End1; 53175569331642446be05292e3e1f8a51218827168cdclaireho 53185569331642446be05292e3e1f8a51218827168cdclaireho next_chainposclassrule: 53195569331642446be05292e3e1f8a51218827168cdclaireho ; 53205569331642446be05292e3e1f8a51218827168cdclaireho } 53215569331642446be05292e3e1f8a51218827168cdclaireho 53225569331642446be05292e3e1f8a51218827168cdclaireho error = HB_Err_Not_Covered; 53235569331642446be05292e3e1f8a51218827168cdclaireho 53245569331642446be05292e3e1f8a51218827168cdclairehoEnd1: 53255569331642446be05292e3e1f8a51218827168cdclaireho FREE( lookahead_classes ); 53265569331642446be05292e3e1f8a51218827168cdclaireho 53275569331642446be05292e3e1f8a51218827168cdclairehoEnd2: 53285569331642446be05292e3e1f8a51218827168cdclaireho FREE( input_classes ); 53295569331642446be05292e3e1f8a51218827168cdclaireho 53305569331642446be05292e3e1f8a51218827168cdclairehoEnd3: 53315569331642446be05292e3e1f8a51218827168cdclaireho FREE( backtrack_classes ); 53325569331642446be05292e3e1f8a51218827168cdclaireho return error; 53335569331642446be05292e3e1f8a51218827168cdclaireho} 53345569331642446be05292e3e1f8a51218827168cdclaireho 53355569331642446be05292e3e1f8a51218827168cdclaireho 53365569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Lookup_ChainContextPos3( 53375569331642446be05292e3e1f8a51218827168cdclaireho GPOS_Instance* gpi, 53385569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainContextPosFormat3* ccpf3, 53395569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 53405569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort flags, 53415569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 53425569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 53435569331642446be05292e3e1f8a51218827168cdclaireho{ 53445569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort index, i, j, property; 53455569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort bgc, igc, lgc; 53465569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 53475569331642446be05292e3e1f8a51218827168cdclaireho HB_GPOSHeader* gpos = gpi->gpos; 53485569331642446be05292e3e1f8a51218827168cdclaireho 53495569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage* bc; 53505569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage* ic; 53515569331642446be05292e3e1f8a51218827168cdclaireho HB_Coverage* lc; 53525569331642446be05292e3e1f8a51218827168cdclaireho HB_GDEFHeader* gdef; 53535569331642446be05292e3e1f8a51218827168cdclaireho 53545569331642446be05292e3e1f8a51218827168cdclaireho 53555569331642446be05292e3e1f8a51218827168cdclaireho gdef = gpos->gdef; 53565569331642446be05292e3e1f8a51218827168cdclaireho 53575569331642446be05292e3e1f8a51218827168cdclaireho if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) ) 53585569331642446be05292e3e1f8a51218827168cdclaireho return error; 53595569331642446be05292e3e1f8a51218827168cdclaireho 53605569331642446be05292e3e1f8a51218827168cdclaireho bgc = ccpf3->BacktrackGlyphCount; 53615569331642446be05292e3e1f8a51218827168cdclaireho igc = ccpf3->InputGlyphCount; 53625569331642446be05292e3e1f8a51218827168cdclaireho lgc = ccpf3->LookaheadGlyphCount; 53635569331642446be05292e3e1f8a51218827168cdclaireho 53645569331642446be05292e3e1f8a51218827168cdclaireho if ( context_length != 0xFFFF && context_length < igc ) 53655569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 53665569331642446be05292e3e1f8a51218827168cdclaireho 53675569331642446be05292e3e1f8a51218827168cdclaireho /* check whether context is too long; it is a first guess only */ 53685569331642446be05292e3e1f8a51218827168cdclaireho 53695569331642446be05292e3e1f8a51218827168cdclaireho if ( bgc > buffer->in_pos || buffer->in_pos + igc + lgc > buffer->in_length ) 53705569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 53715569331642446be05292e3e1f8a51218827168cdclaireho 53725569331642446be05292e3e1f8a51218827168cdclaireho if ( bgc ) 53735569331642446be05292e3e1f8a51218827168cdclaireho { 53745569331642446be05292e3e1f8a51218827168cdclaireho /* Since we don't know in advance the number of glyphs to inspect, 53755569331642446be05292e3e1f8a51218827168cdclaireho we search backwards for matches in the backtrack glyph array */ 53765569331642446be05292e3e1f8a51218827168cdclaireho 53775569331642446be05292e3e1f8a51218827168cdclaireho bc = ccpf3->BacktrackCoverage; 53785569331642446be05292e3e1f8a51218827168cdclaireho 53795569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 0, j = buffer->in_pos - 1; i < bgc; i++, j-- ) 53805569331642446be05292e3e1f8a51218827168cdclaireho { 53815569331642446be05292e3e1f8a51218827168cdclaireho while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) 53825569331642446be05292e3e1f8a51218827168cdclaireho { 53835569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 53845569331642446be05292e3e1f8a51218827168cdclaireho return error; 53855569331642446be05292e3e1f8a51218827168cdclaireho 53865569331642446be05292e3e1f8a51218827168cdclaireho if ( j + 1 == bgc - i ) 53875569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 53885569331642446be05292e3e1f8a51218827168cdclaireho j--; 53895569331642446be05292e3e1f8a51218827168cdclaireho } 53905569331642446be05292e3e1f8a51218827168cdclaireho 53915569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &bc[i], IN_GLYPH( j ), &index ); 53925569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 53935569331642446be05292e3e1f8a51218827168cdclaireho return error; 53945569331642446be05292e3e1f8a51218827168cdclaireho } 53955569331642446be05292e3e1f8a51218827168cdclaireho } 53965569331642446be05292e3e1f8a51218827168cdclaireho 53975569331642446be05292e3e1f8a51218827168cdclaireho ic = ccpf3->InputCoverage; 53985569331642446be05292e3e1f8a51218827168cdclaireho 53995569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 0, j = buffer->in_pos; i < igc; i++, j++ ) 54005569331642446be05292e3e1f8a51218827168cdclaireho { 54015569331642446be05292e3e1f8a51218827168cdclaireho /* We already called CHECK_Property for IN_GLYPH ( buffer->in_pos ) */ 54025569331642446be05292e3e1f8a51218827168cdclaireho while ( j > buffer->in_pos && CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) 54035569331642446be05292e3e1f8a51218827168cdclaireho { 54045569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 54055569331642446be05292e3e1f8a51218827168cdclaireho return error; 54065569331642446be05292e3e1f8a51218827168cdclaireho 54075569331642446be05292e3e1f8a51218827168cdclaireho if ( j + igc - i + lgc == (HB_Int)buffer->in_length ) 54085569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 54095569331642446be05292e3e1f8a51218827168cdclaireho j++; 54105569331642446be05292e3e1f8a51218827168cdclaireho } 54115569331642446be05292e3e1f8a51218827168cdclaireho 54125569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &ic[i], IN_GLYPH( j ), &index ); 54135569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 54145569331642446be05292e3e1f8a51218827168cdclaireho return error; 54155569331642446be05292e3e1f8a51218827168cdclaireho } 54165569331642446be05292e3e1f8a51218827168cdclaireho 54175569331642446be05292e3e1f8a51218827168cdclaireho /* we are starting to check for lookahead glyphs right after the 54185569331642446be05292e3e1f8a51218827168cdclaireho last context glyph */ 54195569331642446be05292e3e1f8a51218827168cdclaireho 54205569331642446be05292e3e1f8a51218827168cdclaireho lc = ccpf3->LookaheadCoverage; 54215569331642446be05292e3e1f8a51218827168cdclaireho 54225569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 0; i < lgc; i++, j++ ) 54235569331642446be05292e3e1f8a51218827168cdclaireho { 54245569331642446be05292e3e1f8a51218827168cdclaireho while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) ) 54255569331642446be05292e3e1f8a51218827168cdclaireho { 54265569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 54275569331642446be05292e3e1f8a51218827168cdclaireho return error; 54285569331642446be05292e3e1f8a51218827168cdclaireho 54295569331642446be05292e3e1f8a51218827168cdclaireho if ( j + lgc - i == (HB_Int)buffer->in_length ) 54305569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 54315569331642446be05292e3e1f8a51218827168cdclaireho j++; 54325569331642446be05292e3e1f8a51218827168cdclaireho } 54335569331642446be05292e3e1f8a51218827168cdclaireho 54345569331642446be05292e3e1f8a51218827168cdclaireho error = _HB_OPEN_Coverage_Index( &lc[i], IN_GLYPH( j ), &index ); 54355569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 54365569331642446be05292e3e1f8a51218827168cdclaireho return error; 54375569331642446be05292e3e1f8a51218827168cdclaireho } 54385569331642446be05292e3e1f8a51218827168cdclaireho 54395569331642446be05292e3e1f8a51218827168cdclaireho return Do_ContextPos( gpi, igc, 54405569331642446be05292e3e1f8a51218827168cdclaireho ccpf3->PosCount, 54415569331642446be05292e3e1f8a51218827168cdclaireho ccpf3->PosLookupRecord, 54425569331642446be05292e3e1f8a51218827168cdclaireho buffer, 54435569331642446be05292e3e1f8a51218827168cdclaireho nesting_level ); 54445569331642446be05292e3e1f8a51218827168cdclaireho} 54455569331642446be05292e3e1f8a51218827168cdclaireho 54465569331642446be05292e3e1f8a51218827168cdclaireho 54475569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Lookup_ChainContextPos( 54485569331642446be05292e3e1f8a51218827168cdclaireho GPOS_Instance* gpi, 54495569331642446be05292e3e1f8a51218827168cdclaireho HB_GPOS_SubTable* st, 54505569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 54515569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort flags, 54525569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 54535569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 54545569331642446be05292e3e1f8a51218827168cdclaireho{ 54555569331642446be05292e3e1f8a51218827168cdclaireho HB_ChainContextPos* ccp = &st->chain; 54565569331642446be05292e3e1f8a51218827168cdclaireho 54575569331642446be05292e3e1f8a51218827168cdclaireho switch ( ccp->PosFormat ) 54585569331642446be05292e3e1f8a51218827168cdclaireho { 54595569331642446be05292e3e1f8a51218827168cdclaireho case 1: 54605569331642446be05292e3e1f8a51218827168cdclaireho return Lookup_ChainContextPos1( gpi, &ccp->ccpf.ccpf1, buffer, 54615569331642446be05292e3e1f8a51218827168cdclaireho flags, context_length, 54625569331642446be05292e3e1f8a51218827168cdclaireho nesting_level ); 54635569331642446be05292e3e1f8a51218827168cdclaireho 54645569331642446be05292e3e1f8a51218827168cdclaireho case 2: 54655569331642446be05292e3e1f8a51218827168cdclaireho return Lookup_ChainContextPos2( gpi, &ccp->ccpf.ccpf2, buffer, 54665569331642446be05292e3e1f8a51218827168cdclaireho flags, context_length, 54675569331642446be05292e3e1f8a51218827168cdclaireho nesting_level ); 54685569331642446be05292e3e1f8a51218827168cdclaireho 54695569331642446be05292e3e1f8a51218827168cdclaireho case 3: 54705569331642446be05292e3e1f8a51218827168cdclaireho return Lookup_ChainContextPos3( gpi, &ccp->ccpf.ccpf3, buffer, 54715569331642446be05292e3e1f8a51218827168cdclaireho flags, context_length, 54725569331642446be05292e3e1f8a51218827168cdclaireho nesting_level ); 54735569331642446be05292e3e1f8a51218827168cdclaireho 54745569331642446be05292e3e1f8a51218827168cdclaireho default: 54755569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable_Format); 54765569331642446be05292e3e1f8a51218827168cdclaireho } 54775569331642446be05292e3e1f8a51218827168cdclaireho 54785569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; /* never reached */ 54795569331642446be05292e3e1f8a51218827168cdclaireho} 54805569331642446be05292e3e1f8a51218827168cdclaireho 54815569331642446be05292e3e1f8a51218827168cdclaireho 54825569331642446be05292e3e1f8a51218827168cdclaireho 54835569331642446be05292e3e1f8a51218827168cdclaireho/*********** 54845569331642446be05292e3e1f8a51218827168cdclaireho * GPOS API 54855569331642446be05292e3e1f8a51218827168cdclaireho ***********/ 54865569331642446be05292e3e1f8a51218827168cdclaireho 54875569331642446be05292e3e1f8a51218827168cdclaireho 54885569331642446be05292e3e1f8a51218827168cdclaireho 54895569331642446be05292e3e1f8a51218827168cdclairehoHB_Error HB_GPOS_Select_Script( HB_GPOSHeader* gpos, 54905569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt script_tag, 54915569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* script_index ) 54925569331642446be05292e3e1f8a51218827168cdclaireho{ 54935569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n; 54945569331642446be05292e3e1f8a51218827168cdclaireho 54955569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptList* sl; 54965569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptRecord* sr; 54975569331642446be05292e3e1f8a51218827168cdclaireho 54985569331642446be05292e3e1f8a51218827168cdclaireho 54995569331642446be05292e3e1f8a51218827168cdclaireho if ( !gpos || !script_index ) 55005569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 55015569331642446be05292e3e1f8a51218827168cdclaireho 55025569331642446be05292e3e1f8a51218827168cdclaireho sl = &gpos->ScriptList; 55035569331642446be05292e3e1f8a51218827168cdclaireho sr = sl->ScriptRecord; 55045569331642446be05292e3e1f8a51218827168cdclaireho 55055569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < sl->ScriptCount; n++ ) 55065569331642446be05292e3e1f8a51218827168cdclaireho if ( script_tag == sr[n].ScriptTag ) 55075569331642446be05292e3e1f8a51218827168cdclaireho { 55085569331642446be05292e3e1f8a51218827168cdclaireho *script_index = n; 55095569331642446be05292e3e1f8a51218827168cdclaireho 55105569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 55115569331642446be05292e3e1f8a51218827168cdclaireho } 55125569331642446be05292e3e1f8a51218827168cdclaireho 55135569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 55145569331642446be05292e3e1f8a51218827168cdclaireho} 55155569331642446be05292e3e1f8a51218827168cdclaireho 55165569331642446be05292e3e1f8a51218827168cdclaireho 55175569331642446be05292e3e1f8a51218827168cdclaireho 55185569331642446be05292e3e1f8a51218827168cdclairehoHB_Error HB_GPOS_Select_Language( HB_GPOSHeader* gpos, 55195569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt language_tag, 55205569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort script_index, 55215569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* language_index, 55225569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* req_feature_index ) 55235569331642446be05292e3e1f8a51218827168cdclaireho{ 55245569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n; 55255569331642446be05292e3e1f8a51218827168cdclaireho 55265569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptList* sl; 55275569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptRecord* sr; 55285569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptTable* s; 55295569331642446be05292e3e1f8a51218827168cdclaireho HB_LangSysRecord* lsr; 55305569331642446be05292e3e1f8a51218827168cdclaireho 55315569331642446be05292e3e1f8a51218827168cdclaireho 55325569331642446be05292e3e1f8a51218827168cdclaireho if ( !gpos || !language_index || !req_feature_index ) 55335569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 55345569331642446be05292e3e1f8a51218827168cdclaireho 55355569331642446be05292e3e1f8a51218827168cdclaireho sl = &gpos->ScriptList; 55365569331642446be05292e3e1f8a51218827168cdclaireho sr = sl->ScriptRecord; 55375569331642446be05292e3e1f8a51218827168cdclaireho 55385569331642446be05292e3e1f8a51218827168cdclaireho if ( script_index >= sl->ScriptCount ) 55395569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 55405569331642446be05292e3e1f8a51218827168cdclaireho 55415569331642446be05292e3e1f8a51218827168cdclaireho s = &sr[script_index].Script; 55425569331642446be05292e3e1f8a51218827168cdclaireho lsr = s->LangSysRecord; 55435569331642446be05292e3e1f8a51218827168cdclaireho 55445569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < s->LangSysCount; n++ ) 55455569331642446be05292e3e1f8a51218827168cdclaireho if ( language_tag == lsr[n].LangSysTag ) 55465569331642446be05292e3e1f8a51218827168cdclaireho { 55475569331642446be05292e3e1f8a51218827168cdclaireho *language_index = n; 55485569331642446be05292e3e1f8a51218827168cdclaireho *req_feature_index = lsr[n].LangSys.ReqFeatureIndex; 55495569331642446be05292e3e1f8a51218827168cdclaireho 55505569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 55515569331642446be05292e3e1f8a51218827168cdclaireho } 55525569331642446be05292e3e1f8a51218827168cdclaireho 55535569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 55545569331642446be05292e3e1f8a51218827168cdclaireho} 55555569331642446be05292e3e1f8a51218827168cdclaireho 55565569331642446be05292e3e1f8a51218827168cdclaireho 55575569331642446be05292e3e1f8a51218827168cdclaireho/* selecting 0xFFFF for language_index asks for the values of the 55585569331642446be05292e3e1f8a51218827168cdclaireho default language (DefaultLangSys) */ 55595569331642446be05292e3e1f8a51218827168cdclaireho 55605569331642446be05292e3e1f8a51218827168cdclaireho 55615569331642446be05292e3e1f8a51218827168cdclairehoHB_Error HB_GPOS_Select_Feature( HB_GPOSHeader* gpos, 55625569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt feature_tag, 55635569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort script_index, 55645569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort language_index, 55655569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* feature_index ) 55665569331642446be05292e3e1f8a51218827168cdclaireho{ 55675569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n; 55685569331642446be05292e3e1f8a51218827168cdclaireho 55695569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptList* sl; 55705569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptRecord* sr; 55715569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptTable* s; 55725569331642446be05292e3e1f8a51218827168cdclaireho HB_LangSysRecord* lsr; 55735569331642446be05292e3e1f8a51218827168cdclaireho HB_LangSys* ls; 55745569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* fi; 55755569331642446be05292e3e1f8a51218827168cdclaireho 55765569331642446be05292e3e1f8a51218827168cdclaireho HB_FeatureList* fl; 55775569331642446be05292e3e1f8a51218827168cdclaireho HB_FeatureRecord* fr; 55785569331642446be05292e3e1f8a51218827168cdclaireho 55795569331642446be05292e3e1f8a51218827168cdclaireho 55805569331642446be05292e3e1f8a51218827168cdclaireho if ( !gpos || !feature_index ) 55815569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 55825569331642446be05292e3e1f8a51218827168cdclaireho 55835569331642446be05292e3e1f8a51218827168cdclaireho sl = &gpos->ScriptList; 55845569331642446be05292e3e1f8a51218827168cdclaireho sr = sl->ScriptRecord; 55855569331642446be05292e3e1f8a51218827168cdclaireho 55865569331642446be05292e3e1f8a51218827168cdclaireho fl = &gpos->FeatureList; 55875569331642446be05292e3e1f8a51218827168cdclaireho fr = fl->FeatureRecord; 55885569331642446be05292e3e1f8a51218827168cdclaireho 55895569331642446be05292e3e1f8a51218827168cdclaireho if ( script_index >= sl->ScriptCount ) 55905569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 55915569331642446be05292e3e1f8a51218827168cdclaireho 55925569331642446be05292e3e1f8a51218827168cdclaireho s = &sr[script_index].Script; 55935569331642446be05292e3e1f8a51218827168cdclaireho lsr = s->LangSysRecord; 55945569331642446be05292e3e1f8a51218827168cdclaireho 55955569331642446be05292e3e1f8a51218827168cdclaireho if ( language_index == 0xFFFF ) 55965569331642446be05292e3e1f8a51218827168cdclaireho ls = &s->DefaultLangSys; 55975569331642446be05292e3e1f8a51218827168cdclaireho else 55985569331642446be05292e3e1f8a51218827168cdclaireho { 55995569331642446be05292e3e1f8a51218827168cdclaireho if ( language_index >= s->LangSysCount ) 56005569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 56015569331642446be05292e3e1f8a51218827168cdclaireho 56025569331642446be05292e3e1f8a51218827168cdclaireho ls = &lsr[language_index].LangSys; 56035569331642446be05292e3e1f8a51218827168cdclaireho } 56045569331642446be05292e3e1f8a51218827168cdclaireho 56055569331642446be05292e3e1f8a51218827168cdclaireho fi = ls->FeatureIndex; 56065569331642446be05292e3e1f8a51218827168cdclaireho 56075569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < ls->FeatureCount; n++ ) 56085569331642446be05292e3e1f8a51218827168cdclaireho { 56095569331642446be05292e3e1f8a51218827168cdclaireho if ( fi[n] >= fl->FeatureCount ) 56105569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable_Format); 56115569331642446be05292e3e1f8a51218827168cdclaireho 56125569331642446be05292e3e1f8a51218827168cdclaireho if ( feature_tag == fr[fi[n]].FeatureTag ) 56135569331642446be05292e3e1f8a51218827168cdclaireho { 56145569331642446be05292e3e1f8a51218827168cdclaireho *feature_index = fi[n]; 56155569331642446be05292e3e1f8a51218827168cdclaireho 56165569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 56175569331642446be05292e3e1f8a51218827168cdclaireho } 56185569331642446be05292e3e1f8a51218827168cdclaireho } 56195569331642446be05292e3e1f8a51218827168cdclaireho 56205569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 56215569331642446be05292e3e1f8a51218827168cdclaireho} 56225569331642446be05292e3e1f8a51218827168cdclaireho 56235569331642446be05292e3e1f8a51218827168cdclaireho 56245569331642446be05292e3e1f8a51218827168cdclaireho/* The next three functions return a null-terminated list */ 56255569331642446be05292e3e1f8a51218827168cdclaireho 56265569331642446be05292e3e1f8a51218827168cdclaireho 56275569331642446be05292e3e1f8a51218827168cdclairehoHB_Error HB_GPOS_Query_Scripts( HB_GPOSHeader* gpos, 56285569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt** script_tag_list ) 56295569331642446be05292e3e1f8a51218827168cdclaireho{ 56305569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 56315569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n; 56325569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt* stl; 56335569331642446be05292e3e1f8a51218827168cdclaireho 56345569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptList* sl; 56355569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptRecord* sr; 56365569331642446be05292e3e1f8a51218827168cdclaireho 56375569331642446be05292e3e1f8a51218827168cdclaireho 56385569331642446be05292e3e1f8a51218827168cdclaireho if ( !gpos || !script_tag_list ) 56395569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 56405569331642446be05292e3e1f8a51218827168cdclaireho 56415569331642446be05292e3e1f8a51218827168cdclaireho sl = &gpos->ScriptList; 56425569331642446be05292e3e1f8a51218827168cdclaireho sr = sl->ScriptRecord; 56435569331642446be05292e3e1f8a51218827168cdclaireho 56445569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( stl, sl->ScriptCount + 1, HB_UInt ) ) 56455569331642446be05292e3e1f8a51218827168cdclaireho return error; 56465569331642446be05292e3e1f8a51218827168cdclaireho 56475569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < sl->ScriptCount; n++ ) 56485569331642446be05292e3e1f8a51218827168cdclaireho stl[n] = sr[n].ScriptTag; 56495569331642446be05292e3e1f8a51218827168cdclaireho stl[n] = 0; 56505569331642446be05292e3e1f8a51218827168cdclaireho 56515569331642446be05292e3e1f8a51218827168cdclaireho *script_tag_list = stl; 56525569331642446be05292e3e1f8a51218827168cdclaireho 56535569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 56545569331642446be05292e3e1f8a51218827168cdclaireho} 56555569331642446be05292e3e1f8a51218827168cdclaireho 56565569331642446be05292e3e1f8a51218827168cdclaireho 56575569331642446be05292e3e1f8a51218827168cdclaireho 56585569331642446be05292e3e1f8a51218827168cdclairehoHB_Error HB_GPOS_Query_Languages( HB_GPOSHeader* gpos, 56595569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort script_index, 56605569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt** language_tag_list ) 56615569331642446be05292e3e1f8a51218827168cdclaireho{ 56625569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 56635569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n; 56645569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt* ltl; 56655569331642446be05292e3e1f8a51218827168cdclaireho 56665569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptList* sl; 56675569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptRecord* sr; 56685569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptTable* s; 56695569331642446be05292e3e1f8a51218827168cdclaireho HB_LangSysRecord* lsr; 56705569331642446be05292e3e1f8a51218827168cdclaireho 56715569331642446be05292e3e1f8a51218827168cdclaireho 56725569331642446be05292e3e1f8a51218827168cdclaireho if ( !gpos || !language_tag_list ) 56735569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 56745569331642446be05292e3e1f8a51218827168cdclaireho 56755569331642446be05292e3e1f8a51218827168cdclaireho sl = &gpos->ScriptList; 56765569331642446be05292e3e1f8a51218827168cdclaireho sr = sl->ScriptRecord; 56775569331642446be05292e3e1f8a51218827168cdclaireho 56785569331642446be05292e3e1f8a51218827168cdclaireho if ( script_index >= sl->ScriptCount ) 56795569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 56805569331642446be05292e3e1f8a51218827168cdclaireho 56815569331642446be05292e3e1f8a51218827168cdclaireho s = &sr[script_index].Script; 56825569331642446be05292e3e1f8a51218827168cdclaireho lsr = s->LangSysRecord; 56835569331642446be05292e3e1f8a51218827168cdclaireho 56845569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( ltl, s->LangSysCount + 1, HB_UInt ) ) 56855569331642446be05292e3e1f8a51218827168cdclaireho return error; 56865569331642446be05292e3e1f8a51218827168cdclaireho 56875569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < s->LangSysCount; n++ ) 56885569331642446be05292e3e1f8a51218827168cdclaireho ltl[n] = lsr[n].LangSysTag; 56895569331642446be05292e3e1f8a51218827168cdclaireho ltl[n] = 0; 56905569331642446be05292e3e1f8a51218827168cdclaireho 56915569331642446be05292e3e1f8a51218827168cdclaireho *language_tag_list = ltl; 56925569331642446be05292e3e1f8a51218827168cdclaireho 56935569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 56945569331642446be05292e3e1f8a51218827168cdclaireho} 56955569331642446be05292e3e1f8a51218827168cdclaireho 56965569331642446be05292e3e1f8a51218827168cdclaireho 56975569331642446be05292e3e1f8a51218827168cdclaireho/* selecting 0xFFFF for language_index asks for the values of the 56985569331642446be05292e3e1f8a51218827168cdclaireho default language (DefaultLangSys) */ 56995569331642446be05292e3e1f8a51218827168cdclaireho 57005569331642446be05292e3e1f8a51218827168cdclaireho 57015569331642446be05292e3e1f8a51218827168cdclairehoHB_Error HB_GPOS_Query_Features( HB_GPOSHeader* gpos, 57025569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort script_index, 57035569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort language_index, 57045569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt** feature_tag_list ) 57055569331642446be05292e3e1f8a51218827168cdclaireho{ 57065569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort n; 57075569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error; 57085569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt* ftl; 57095569331642446be05292e3e1f8a51218827168cdclaireho 57105569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptList* sl; 57115569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptRecord* sr; 57125569331642446be05292e3e1f8a51218827168cdclaireho HB_ScriptTable* s; 57135569331642446be05292e3e1f8a51218827168cdclaireho HB_LangSysRecord* lsr; 57145569331642446be05292e3e1f8a51218827168cdclaireho HB_LangSys* ls; 57155569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* fi; 57165569331642446be05292e3e1f8a51218827168cdclaireho 57175569331642446be05292e3e1f8a51218827168cdclaireho HB_FeatureList* fl; 57185569331642446be05292e3e1f8a51218827168cdclaireho HB_FeatureRecord* fr; 57195569331642446be05292e3e1f8a51218827168cdclaireho 57205569331642446be05292e3e1f8a51218827168cdclaireho 57215569331642446be05292e3e1f8a51218827168cdclaireho if ( !gpos || !feature_tag_list ) 57225569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 57235569331642446be05292e3e1f8a51218827168cdclaireho 57245569331642446be05292e3e1f8a51218827168cdclaireho sl = &gpos->ScriptList; 57255569331642446be05292e3e1f8a51218827168cdclaireho sr = sl->ScriptRecord; 57265569331642446be05292e3e1f8a51218827168cdclaireho 57275569331642446be05292e3e1f8a51218827168cdclaireho fl = &gpos->FeatureList; 57285569331642446be05292e3e1f8a51218827168cdclaireho fr = fl->FeatureRecord; 57295569331642446be05292e3e1f8a51218827168cdclaireho 57305569331642446be05292e3e1f8a51218827168cdclaireho if ( script_index >= sl->ScriptCount ) 57315569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 57325569331642446be05292e3e1f8a51218827168cdclaireho 57335569331642446be05292e3e1f8a51218827168cdclaireho s = &sr[script_index].Script; 57345569331642446be05292e3e1f8a51218827168cdclaireho lsr = s->LangSysRecord; 57355569331642446be05292e3e1f8a51218827168cdclaireho 57365569331642446be05292e3e1f8a51218827168cdclaireho if ( language_index == 0xFFFF ) 57375569331642446be05292e3e1f8a51218827168cdclaireho ls = &s->DefaultLangSys; 57385569331642446be05292e3e1f8a51218827168cdclaireho else 57395569331642446be05292e3e1f8a51218827168cdclaireho { 57405569331642446be05292e3e1f8a51218827168cdclaireho if ( language_index >= s->LangSysCount ) 57415569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 57425569331642446be05292e3e1f8a51218827168cdclaireho 57435569331642446be05292e3e1f8a51218827168cdclaireho ls = &lsr[language_index].LangSys; 57445569331642446be05292e3e1f8a51218827168cdclaireho } 57455569331642446be05292e3e1f8a51218827168cdclaireho 57465569331642446be05292e3e1f8a51218827168cdclaireho fi = ls->FeatureIndex; 57475569331642446be05292e3e1f8a51218827168cdclaireho 57485569331642446be05292e3e1f8a51218827168cdclaireho if ( ALLOC_ARRAY( ftl, ls->FeatureCount + 1, HB_UInt ) ) 57495569331642446be05292e3e1f8a51218827168cdclaireho return error; 57505569331642446be05292e3e1f8a51218827168cdclaireho 57515569331642446be05292e3e1f8a51218827168cdclaireho for ( n = 0; n < ls->FeatureCount; n++ ) 57525569331642446be05292e3e1f8a51218827168cdclaireho { 57535569331642446be05292e3e1f8a51218827168cdclaireho if ( fi[n] >= fl->FeatureCount ) 57545569331642446be05292e3e1f8a51218827168cdclaireho { 57555569331642446be05292e3e1f8a51218827168cdclaireho FREE( ftl ); 57565569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_SubTable_Format); 57575569331642446be05292e3e1f8a51218827168cdclaireho } 57585569331642446be05292e3e1f8a51218827168cdclaireho ftl[n] = fr[fi[n]].FeatureTag; 57595569331642446be05292e3e1f8a51218827168cdclaireho } 57605569331642446be05292e3e1f8a51218827168cdclaireho ftl[n] = 0; 57615569331642446be05292e3e1f8a51218827168cdclaireho 57625569331642446be05292e3e1f8a51218827168cdclaireho *feature_tag_list = ftl; 57635569331642446be05292e3e1f8a51218827168cdclaireho 57645569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 57655569331642446be05292e3e1f8a51218827168cdclaireho} 57665569331642446be05292e3e1f8a51218827168cdclaireho 57675569331642446be05292e3e1f8a51218827168cdclaireho 57685569331642446be05292e3e1f8a51218827168cdclaireho/* Do an individual subtable lookup. Returns HB_Err_Ok if positioning 57695569331642446be05292e3e1f8a51218827168cdclaireho has been done, or HB_Err_Not_Covered if not. */ 57705569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error GPOS_Do_Glyph_Lookup( GPOS_Instance* gpi, 57715569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort lookup_index, 57725569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 57735569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort context_length, 57745569331642446be05292e3e1f8a51218827168cdclaireho int nesting_level ) 57755569331642446be05292e3e1f8a51218827168cdclaireho{ 57765569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error = HB_Err_Not_Covered; 57775569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort i, flags, lookup_count; 57785569331642446be05292e3e1f8a51218827168cdclaireho HB_GPOSHeader* gpos = gpi->gpos; 57795569331642446be05292e3e1f8a51218827168cdclaireho HB_Lookup* lo; 57805569331642446be05292e3e1f8a51218827168cdclaireho int lookup_type; 57815569331642446be05292e3e1f8a51218827168cdclaireho 57825569331642446be05292e3e1f8a51218827168cdclaireho 57835569331642446be05292e3e1f8a51218827168cdclaireho nesting_level++; 57845569331642446be05292e3e1f8a51218827168cdclaireho 57855569331642446be05292e3e1f8a51218827168cdclaireho if ( nesting_level > HB_MAX_NESTING_LEVEL ) 57865569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Not_Covered); /* ERR() call intended */ 57875569331642446be05292e3e1f8a51218827168cdclaireho 57885569331642446be05292e3e1f8a51218827168cdclaireho lookup_count = gpos->LookupList.LookupCount; 57895569331642446be05292e3e1f8a51218827168cdclaireho if (lookup_index >= lookup_count) 57905569331642446be05292e3e1f8a51218827168cdclaireho return error; 57915569331642446be05292e3e1f8a51218827168cdclaireho 57925569331642446be05292e3e1f8a51218827168cdclaireho lo = &gpos->LookupList.Lookup[lookup_index]; 57935569331642446be05292e3e1f8a51218827168cdclaireho flags = lo->LookupFlag; 57945569331642446be05292e3e1f8a51218827168cdclaireho lookup_type = lo->LookupType; 57955569331642446be05292e3e1f8a51218827168cdclaireho 57965569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 0; i < lo->SubTableCount; i++ ) 57975569331642446be05292e3e1f8a51218827168cdclaireho { 57985569331642446be05292e3e1f8a51218827168cdclaireho HB_GPOS_SubTable *st = &lo->SubTable[i].st.gpos; 57995569331642446be05292e3e1f8a51218827168cdclaireho 58005569331642446be05292e3e1f8a51218827168cdclaireho switch (lookup_type) { 58015569331642446be05292e3e1f8a51218827168cdclaireho case HB_GPOS_LOOKUP_SINGLE: 58025569331642446be05292e3e1f8a51218827168cdclaireho error = Lookup_SinglePos ( gpi, st, buffer, flags, context_length, nesting_level ); break; 58035569331642446be05292e3e1f8a51218827168cdclaireho case HB_GPOS_LOOKUP_PAIR: 58045569331642446be05292e3e1f8a51218827168cdclaireho error = Lookup_PairPos ( gpi, st, buffer, flags, context_length, nesting_level ); break; 58055569331642446be05292e3e1f8a51218827168cdclaireho case HB_GPOS_LOOKUP_CURSIVE: 58065569331642446be05292e3e1f8a51218827168cdclaireho error = Lookup_CursivePos ( gpi, st, buffer, flags, context_length, nesting_level ); break; 58075569331642446be05292e3e1f8a51218827168cdclaireho case HB_GPOS_LOOKUP_MARKBASE: 58085569331642446be05292e3e1f8a51218827168cdclaireho error = Lookup_MarkBasePos ( gpi, st, buffer, flags, context_length, nesting_level ); break; 58095569331642446be05292e3e1f8a51218827168cdclaireho case HB_GPOS_LOOKUP_MARKLIG: 58105569331642446be05292e3e1f8a51218827168cdclaireho error = Lookup_MarkLigPos ( gpi, st, buffer, flags, context_length, nesting_level ); break; 58115569331642446be05292e3e1f8a51218827168cdclaireho case HB_GPOS_LOOKUP_MARKMARK: 58125569331642446be05292e3e1f8a51218827168cdclaireho error = Lookup_MarkMarkPos ( gpi, st, buffer, flags, context_length, nesting_level ); break; 58135569331642446be05292e3e1f8a51218827168cdclaireho case HB_GPOS_LOOKUP_CONTEXT: 58145569331642446be05292e3e1f8a51218827168cdclaireho error = Lookup_ContextPos ( gpi, st, buffer, flags, context_length, nesting_level ); break; 58155569331642446be05292e3e1f8a51218827168cdclaireho case HB_GPOS_LOOKUP_CHAIN: 58165569331642446be05292e3e1f8a51218827168cdclaireho error = Lookup_ChainContextPos ( gpi, st, buffer, flags, context_length, nesting_level ); break; 58175569331642446be05292e3e1f8a51218827168cdclaireho /*case HB_GPOS_LOOKUP_EXTENSION: 58185569331642446be05292e3e1f8a51218827168cdclaireho error = Lookup_ExtensionPos ( gpi, st, buffer, flags, context_length, nesting_level ); break;*/ 58195569331642446be05292e3e1f8a51218827168cdclaireho default: 58205569331642446be05292e3e1f8a51218827168cdclaireho error = HB_Err_Not_Covered; 58215569331642446be05292e3e1f8a51218827168cdclaireho } 58225569331642446be05292e3e1f8a51218827168cdclaireho 58235569331642446be05292e3e1f8a51218827168cdclaireho /* Check whether we have a successful positioning or an error other 58245569331642446be05292e3e1f8a51218827168cdclaireho than HB_Err_Not_Covered */ 58255569331642446be05292e3e1f8a51218827168cdclaireho if ( error != HB_Err_Not_Covered ) 58265569331642446be05292e3e1f8a51218827168cdclaireho return error; 58275569331642446be05292e3e1f8a51218827168cdclaireho } 58285569331642446be05292e3e1f8a51218827168cdclaireho 58295569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 58305569331642446be05292e3e1f8a51218827168cdclaireho} 58315569331642446be05292e3e1f8a51218827168cdclaireho 58325569331642446be05292e3e1f8a51218827168cdclaireho 58335569331642446be05292e3e1f8a51218827168cdclairehoHB_INTERNAL HB_Error 58345569331642446be05292e3e1f8a51218827168cdclaireho_HB_GPOS_Load_SubTable( HB_GPOS_SubTable* st, 58355569331642446be05292e3e1f8a51218827168cdclaireho HB_Stream stream, 58365569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort lookup_type ) 58375569331642446be05292e3e1f8a51218827168cdclaireho{ 58385569331642446be05292e3e1f8a51218827168cdclaireho switch ( lookup_type ) { 58395569331642446be05292e3e1f8a51218827168cdclaireho case HB_GPOS_LOOKUP_SINGLE: return Load_SinglePos ( st, stream ); 58405569331642446be05292e3e1f8a51218827168cdclaireho case HB_GPOS_LOOKUP_PAIR: return Load_PairPos ( st, stream ); 58415569331642446be05292e3e1f8a51218827168cdclaireho case HB_GPOS_LOOKUP_CURSIVE: return Load_CursivePos ( st, stream ); 58425569331642446be05292e3e1f8a51218827168cdclaireho case HB_GPOS_LOOKUP_MARKBASE: return Load_MarkBasePos ( st, stream ); 58435569331642446be05292e3e1f8a51218827168cdclaireho case HB_GPOS_LOOKUP_MARKLIG: return Load_MarkLigPos ( st, stream ); 58445569331642446be05292e3e1f8a51218827168cdclaireho case HB_GPOS_LOOKUP_MARKMARK: return Load_MarkMarkPos ( st, stream ); 58455569331642446be05292e3e1f8a51218827168cdclaireho case HB_GPOS_LOOKUP_CONTEXT: return Load_ContextPos ( st, stream ); 58465569331642446be05292e3e1f8a51218827168cdclaireho case HB_GPOS_LOOKUP_CHAIN: return Load_ChainContextPos ( st, stream ); 58475569331642446be05292e3e1f8a51218827168cdclaireho /*case HB_GPOS_LOOKUP_EXTENSION: return Load_ExtensionPos ( st, stream );*/ 58485569331642446be05292e3e1f8a51218827168cdclaireho default: return ERR(HB_Err_Invalid_SubTable_Format); 58495569331642446be05292e3e1f8a51218827168cdclaireho } 58505569331642446be05292e3e1f8a51218827168cdclaireho} 58515569331642446be05292e3e1f8a51218827168cdclaireho 58525569331642446be05292e3e1f8a51218827168cdclaireho 58535569331642446be05292e3e1f8a51218827168cdclairehoHB_INTERNAL void 58545569331642446be05292e3e1f8a51218827168cdclaireho_HB_GPOS_Free_SubTable( HB_GPOS_SubTable* st, 58555569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort lookup_type ) 58565569331642446be05292e3e1f8a51218827168cdclaireho{ 58575569331642446be05292e3e1f8a51218827168cdclaireho switch ( lookup_type ) { 58585569331642446be05292e3e1f8a51218827168cdclaireho case HB_GPOS_LOOKUP_SINGLE: Free_SinglePos ( st ); return; 58595569331642446be05292e3e1f8a51218827168cdclaireho case HB_GPOS_LOOKUP_PAIR: Free_PairPos ( st ); return; 58605569331642446be05292e3e1f8a51218827168cdclaireho case HB_GPOS_LOOKUP_CURSIVE: Free_CursivePos ( st ); return; 58615569331642446be05292e3e1f8a51218827168cdclaireho case HB_GPOS_LOOKUP_MARKBASE: Free_MarkBasePos ( st ); return; 58625569331642446be05292e3e1f8a51218827168cdclaireho case HB_GPOS_LOOKUP_MARKLIG: Free_MarkLigPos ( st ); return; 58635569331642446be05292e3e1f8a51218827168cdclaireho case HB_GPOS_LOOKUP_MARKMARK: Free_MarkMarkPos ( st ); return; 58645569331642446be05292e3e1f8a51218827168cdclaireho case HB_GPOS_LOOKUP_CONTEXT: Free_ContextPos ( st ); return; 58655569331642446be05292e3e1f8a51218827168cdclaireho case HB_GPOS_LOOKUP_CHAIN: Free_ChainContextPos ( st ); return; 58665569331642446be05292e3e1f8a51218827168cdclaireho /*case HB_GPOS_LOOKUP_EXTENSION: Free_ExtensionPos ( st ); return;*/ 58675569331642446be05292e3e1f8a51218827168cdclaireho default: return; 58685569331642446be05292e3e1f8a51218827168cdclaireho } 58695569331642446be05292e3e1f8a51218827168cdclaireho} 58705569331642446be05292e3e1f8a51218827168cdclaireho 58715569331642446be05292e3e1f8a51218827168cdclaireho 58725569331642446be05292e3e1f8a51218827168cdclaireho/* apply one lookup to the input string object */ 58735569331642446be05292e3e1f8a51218827168cdclaireho 58745569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error GPOS_Do_String_Lookup( GPOS_Instance* gpi, 58755569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort lookup_index, 58765569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer ) 58775569331642446be05292e3e1f8a51218827168cdclaireho{ 58785569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error, retError = HB_Err_Not_Covered; 58795569331642446be05292e3e1f8a51218827168cdclaireho HB_GPOSHeader* gpos = gpi->gpos; 58805569331642446be05292e3e1f8a51218827168cdclaireho 58815569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt* properties = gpos->LookupList.Properties; 58825569331642446be05292e3e1f8a51218827168cdclaireho 58835569331642446be05292e3e1f8a51218827168cdclaireho const int nesting_level = 0; 58845569331642446be05292e3e1f8a51218827168cdclaireho /* 0xFFFF indicates that we don't have a context length yet */ 58855569331642446be05292e3e1f8a51218827168cdclaireho const HB_UShort context_length = 0xFFFF; 58865569331642446be05292e3e1f8a51218827168cdclaireho 58875569331642446be05292e3e1f8a51218827168cdclaireho 58885569331642446be05292e3e1f8a51218827168cdclaireho gpi->last = 0xFFFF; /* no last valid glyph for cursive pos. */ 58895569331642446be05292e3e1f8a51218827168cdclaireho 58905569331642446be05292e3e1f8a51218827168cdclaireho buffer->in_pos = 0; 58915569331642446be05292e3e1f8a51218827168cdclaireho while ( buffer->in_pos < buffer->in_length ) 58925569331642446be05292e3e1f8a51218827168cdclaireho { 58935569331642446be05292e3e1f8a51218827168cdclaireho if ( ~IN_PROPERTIES( buffer->in_pos ) & properties[lookup_index] ) 58945569331642446be05292e3e1f8a51218827168cdclaireho { 58955569331642446be05292e3e1f8a51218827168cdclaireho /* Note that the connection between mark and base glyphs hold 58965569331642446be05292e3e1f8a51218827168cdclaireho exactly one (string) lookup. For example, it would be possible 58975569331642446be05292e3e1f8a51218827168cdclaireho that in the first lookup, mark glyph X is attached to base 58985569331642446be05292e3e1f8a51218827168cdclaireho glyph A, and in the next lookup it is attached to base glyph B. 58995569331642446be05292e3e1f8a51218827168cdclaireho It is up to the font designer to provide meaningful lookups and 59005569331642446be05292e3e1f8a51218827168cdclaireho lookup order. */ 59015569331642446be05292e3e1f8a51218827168cdclaireho 59025569331642446be05292e3e1f8a51218827168cdclaireho error = GPOS_Do_Glyph_Lookup( gpi, lookup_index, buffer, context_length, nesting_level ); 59035569331642446be05292e3e1f8a51218827168cdclaireho if ( error && error != HB_Err_Not_Covered ) 59045569331642446be05292e3e1f8a51218827168cdclaireho return error; 59055569331642446be05292e3e1f8a51218827168cdclaireho } 59065569331642446be05292e3e1f8a51218827168cdclaireho else 59075569331642446be05292e3e1f8a51218827168cdclaireho { 59085569331642446be05292e3e1f8a51218827168cdclaireho /* Contrary to properties defined in GDEF, user-defined properties 59095569331642446be05292e3e1f8a51218827168cdclaireho will always stop a possible cursive positioning. */ 59105569331642446be05292e3e1f8a51218827168cdclaireho gpi->last = 0xFFFF; 59115569331642446be05292e3e1f8a51218827168cdclaireho 59125569331642446be05292e3e1f8a51218827168cdclaireho error = HB_Err_Not_Covered; 59135569331642446be05292e3e1f8a51218827168cdclaireho } 59145569331642446be05292e3e1f8a51218827168cdclaireho 59155569331642446be05292e3e1f8a51218827168cdclaireho if ( error == HB_Err_Not_Covered ) 59165569331642446be05292e3e1f8a51218827168cdclaireho (buffer->in_pos)++; 59175569331642446be05292e3e1f8a51218827168cdclaireho else 59185569331642446be05292e3e1f8a51218827168cdclaireho retError = error; 59195569331642446be05292e3e1f8a51218827168cdclaireho } 59205569331642446be05292e3e1f8a51218827168cdclaireho 59215569331642446be05292e3e1f8a51218827168cdclaireho return retError; 59225569331642446be05292e3e1f8a51218827168cdclaireho} 59235569331642446be05292e3e1f8a51218827168cdclaireho 59245569331642446be05292e3e1f8a51218827168cdclaireho 59255569331642446be05292e3e1f8a51218827168cdclairehostatic HB_Error Position_CursiveChain ( HB_Buffer buffer ) 59265569331642446be05292e3e1f8a51218827168cdclaireho{ 59275569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt i, j; 59285569331642446be05292e3e1f8a51218827168cdclaireho HB_Position positions = buffer->positions; 59295569331642446be05292e3e1f8a51218827168cdclaireho 59305569331642446be05292e3e1f8a51218827168cdclaireho /* First handle all left-to-right connections */ 59315569331642446be05292e3e1f8a51218827168cdclaireho for (j = 0; j < buffer->in_length; j++) 59325569331642446be05292e3e1f8a51218827168cdclaireho { 59335569331642446be05292e3e1f8a51218827168cdclaireho if (positions[j].cursive_chain > 0) 59345569331642446be05292e3e1f8a51218827168cdclaireho positions[j].y_pos += positions[j - positions[j].cursive_chain].y_pos; 59355569331642446be05292e3e1f8a51218827168cdclaireho } 59365569331642446be05292e3e1f8a51218827168cdclaireho 59375569331642446be05292e3e1f8a51218827168cdclaireho /* Then handle all right-to-left connections */ 59385569331642446be05292e3e1f8a51218827168cdclaireho for (i = buffer->in_length; i > 0; i--) 59395569331642446be05292e3e1f8a51218827168cdclaireho { 59405569331642446be05292e3e1f8a51218827168cdclaireho j = i - 1; 59415569331642446be05292e3e1f8a51218827168cdclaireho 59425569331642446be05292e3e1f8a51218827168cdclaireho if (positions[j].cursive_chain < 0) 59435569331642446be05292e3e1f8a51218827168cdclaireho positions[j].y_pos += positions[j - positions[j].cursive_chain].y_pos; 59445569331642446be05292e3e1f8a51218827168cdclaireho } 59455569331642446be05292e3e1f8a51218827168cdclaireho 59465569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 59475569331642446be05292e3e1f8a51218827168cdclaireho} 59485569331642446be05292e3e1f8a51218827168cdclaireho 59495569331642446be05292e3e1f8a51218827168cdclaireho 59505569331642446be05292e3e1f8a51218827168cdclairehoHB_Error HB_GPOS_Add_Feature( HB_GPOSHeader* gpos, 59515569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort feature_index, 59525569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt property ) 59535569331642446be05292e3e1f8a51218827168cdclaireho{ 59545569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort i; 59555569331642446be05292e3e1f8a51218827168cdclaireho 59565569331642446be05292e3e1f8a51218827168cdclaireho HB_Feature feature; 59575569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt* properties; 59585569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort* index; 59595569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort lookup_count; 59605569331642446be05292e3e1f8a51218827168cdclaireho 59615569331642446be05292e3e1f8a51218827168cdclaireho /* Each feature can only be added once */ 59625569331642446be05292e3e1f8a51218827168cdclaireho 59635569331642446be05292e3e1f8a51218827168cdclaireho if ( !gpos || 59645569331642446be05292e3e1f8a51218827168cdclaireho feature_index >= gpos->FeatureList.FeatureCount || 59655569331642446be05292e3e1f8a51218827168cdclaireho gpos->FeatureList.ApplyCount == gpos->FeatureList.FeatureCount ) 59665569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 59675569331642446be05292e3e1f8a51218827168cdclaireho 59685569331642446be05292e3e1f8a51218827168cdclaireho gpos->FeatureList.ApplyOrder[gpos->FeatureList.ApplyCount++] = feature_index; 59695569331642446be05292e3e1f8a51218827168cdclaireho 59705569331642446be05292e3e1f8a51218827168cdclaireho properties = gpos->LookupList.Properties; 59715569331642446be05292e3e1f8a51218827168cdclaireho 59725569331642446be05292e3e1f8a51218827168cdclaireho feature = gpos->FeatureList.FeatureRecord[feature_index].Feature; 59735569331642446be05292e3e1f8a51218827168cdclaireho index = feature.LookupListIndex; 59745569331642446be05292e3e1f8a51218827168cdclaireho lookup_count = gpos->LookupList.LookupCount; 59755569331642446be05292e3e1f8a51218827168cdclaireho 59765569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 0; i < feature.LookupListCount; i++ ) 59775569331642446be05292e3e1f8a51218827168cdclaireho { 59785569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort lookup_index = index[i]; 59795569331642446be05292e3e1f8a51218827168cdclaireho if (lookup_index < lookup_count) 59805569331642446be05292e3e1f8a51218827168cdclaireho properties[lookup_index] |= property; 59815569331642446be05292e3e1f8a51218827168cdclaireho } 59825569331642446be05292e3e1f8a51218827168cdclaireho 59835569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 59845569331642446be05292e3e1f8a51218827168cdclaireho} 59855569331642446be05292e3e1f8a51218827168cdclaireho 59865569331642446be05292e3e1f8a51218827168cdclaireho 59875569331642446be05292e3e1f8a51218827168cdclaireho 59885569331642446be05292e3e1f8a51218827168cdclairehoHB_Error HB_GPOS_Clear_Features( HB_GPOSHeader* gpos ) 59895569331642446be05292e3e1f8a51218827168cdclaireho{ 59905569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort i; 59915569331642446be05292e3e1f8a51218827168cdclaireho 59925569331642446be05292e3e1f8a51218827168cdclaireho HB_UInt* properties; 59935569331642446be05292e3e1f8a51218827168cdclaireho 59945569331642446be05292e3e1f8a51218827168cdclaireho 59955569331642446be05292e3e1f8a51218827168cdclaireho if ( !gpos ) 59965569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 59975569331642446be05292e3e1f8a51218827168cdclaireho 59985569331642446be05292e3e1f8a51218827168cdclaireho gpos->FeatureList.ApplyCount = 0; 59995569331642446be05292e3e1f8a51218827168cdclaireho 60005569331642446be05292e3e1f8a51218827168cdclaireho properties = gpos->LookupList.Properties; 60015569331642446be05292e3e1f8a51218827168cdclaireho 60025569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 0; i < gpos->LookupList.LookupCount; i++ ) 60035569331642446be05292e3e1f8a51218827168cdclaireho properties[i] = 0; 60045569331642446be05292e3e1f8a51218827168cdclaireho 60055569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 60065569331642446be05292e3e1f8a51218827168cdclaireho} 60075569331642446be05292e3e1f8a51218827168cdclaireho 600857e6107a9d66a9a97b146def0ef38c010f954be6claireho#ifdef HB_SUPPORT_MULTIPLE_MASTER 60095569331642446be05292e3e1f8a51218827168cdclairehoHB_Error HB_GPOS_Register_MM_Function( HB_GPOSHeader* gpos, 60105569331642446be05292e3e1f8a51218827168cdclaireho HB_MMFunction mmfunc, 60115569331642446be05292e3e1f8a51218827168cdclaireho void* data ) 60125569331642446be05292e3e1f8a51218827168cdclaireho{ 60135569331642446be05292e3e1f8a51218827168cdclaireho if ( !gpos ) 60145569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 60155569331642446be05292e3e1f8a51218827168cdclaireho 60165569331642446be05292e3e1f8a51218827168cdclaireho gpos->mmfunc = mmfunc; 60175569331642446be05292e3e1f8a51218827168cdclaireho gpos->data = data; 60185569331642446be05292e3e1f8a51218827168cdclaireho 60195569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Ok; 60205569331642446be05292e3e1f8a51218827168cdclaireho} 602157e6107a9d66a9a97b146def0ef38c010f954be6claireho#endif 60225569331642446be05292e3e1f8a51218827168cdclaireho 60235569331642446be05292e3e1f8a51218827168cdclaireho/* If `dvi' is TRUE, glyph contour points for anchor points and device 60245569331642446be05292e3e1f8a51218827168cdclaireho tables are ignored -- you will get device independent values. */ 60255569331642446be05292e3e1f8a51218827168cdclaireho 60265569331642446be05292e3e1f8a51218827168cdclaireho 60275569331642446be05292e3e1f8a51218827168cdclairehoHB_Error HB_GPOS_Apply_String( HB_Font font, 60285569331642446be05292e3e1f8a51218827168cdclaireho HB_GPOSHeader* gpos, 60295569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort load_flags, 60305569331642446be05292e3e1f8a51218827168cdclaireho HB_Buffer buffer, 60315569331642446be05292e3e1f8a51218827168cdclaireho HB_Bool dvi, 60325569331642446be05292e3e1f8a51218827168cdclaireho HB_Bool r2l ) 60335569331642446be05292e3e1f8a51218827168cdclaireho{ 60345569331642446be05292e3e1f8a51218827168cdclaireho HB_Error error, retError = HB_Err_Not_Covered; 60355569331642446be05292e3e1f8a51218827168cdclaireho GPOS_Instance gpi; 60365569331642446be05292e3e1f8a51218827168cdclaireho int i, j, lookup_count, num_features; 60375569331642446be05292e3e1f8a51218827168cdclaireho 60385569331642446be05292e3e1f8a51218827168cdclaireho if ( !font || !gpos || !buffer ) 60395569331642446be05292e3e1f8a51218827168cdclaireho return ERR(HB_Err_Invalid_Argument); 60405569331642446be05292e3e1f8a51218827168cdclaireho 60415569331642446be05292e3e1f8a51218827168cdclaireho if ( buffer->in_length == 0 ) 60425569331642446be05292e3e1f8a51218827168cdclaireho return HB_Err_Not_Covered; 60435569331642446be05292e3e1f8a51218827168cdclaireho 60445569331642446be05292e3e1f8a51218827168cdclaireho gpi.font = font; 60455569331642446be05292e3e1f8a51218827168cdclaireho gpi.gpos = gpos; 60465569331642446be05292e3e1f8a51218827168cdclaireho gpi.load_flags = load_flags; 60475569331642446be05292e3e1f8a51218827168cdclaireho gpi.r2l = r2l; 60485569331642446be05292e3e1f8a51218827168cdclaireho gpi.dvi = dvi; 60495569331642446be05292e3e1f8a51218827168cdclaireho 60505569331642446be05292e3e1f8a51218827168cdclaireho lookup_count = gpos->LookupList.LookupCount; 60515569331642446be05292e3e1f8a51218827168cdclaireho num_features = gpos->FeatureList.ApplyCount; 60525569331642446be05292e3e1f8a51218827168cdclaireho 60535569331642446be05292e3e1f8a51218827168cdclaireho if ( num_features ) 60545569331642446be05292e3e1f8a51218827168cdclaireho { 60555569331642446be05292e3e1f8a51218827168cdclaireho error = _hb_buffer_clear_positions( buffer ); 60565569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 60575569331642446be05292e3e1f8a51218827168cdclaireho return error; 60585569331642446be05292e3e1f8a51218827168cdclaireho } 60595569331642446be05292e3e1f8a51218827168cdclaireho 60605569331642446be05292e3e1f8a51218827168cdclaireho for ( i = 0; i < num_features; i++ ) 60615569331642446be05292e3e1f8a51218827168cdclaireho { 60625569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort feature_index = gpos->FeatureList.ApplyOrder[i]; 60635569331642446be05292e3e1f8a51218827168cdclaireho HB_Feature feature = gpos->FeatureList.FeatureRecord[feature_index].Feature; 60645569331642446be05292e3e1f8a51218827168cdclaireho 60655569331642446be05292e3e1f8a51218827168cdclaireho for ( j = 0; j < feature.LookupListCount; j++ ) 60665569331642446be05292e3e1f8a51218827168cdclaireho { 60675569331642446be05292e3e1f8a51218827168cdclaireho HB_UShort lookup_index = feature.LookupListIndex[j]; 60685569331642446be05292e3e1f8a51218827168cdclaireho 60695569331642446be05292e3e1f8a51218827168cdclaireho /* Skip nonexistant lookups */ 60705569331642446be05292e3e1f8a51218827168cdclaireho if (lookup_index >= lookup_count) 60715569331642446be05292e3e1f8a51218827168cdclaireho continue; 60725569331642446be05292e3e1f8a51218827168cdclaireho 60735569331642446be05292e3e1f8a51218827168cdclaireho error = GPOS_Do_String_Lookup( &gpi, lookup_index, buffer ); 60745569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 60755569331642446be05292e3e1f8a51218827168cdclaireho { 60765569331642446be05292e3e1f8a51218827168cdclaireho if ( error != HB_Err_Not_Covered ) 60775569331642446be05292e3e1f8a51218827168cdclaireho return error; 60785569331642446be05292e3e1f8a51218827168cdclaireho } 60795569331642446be05292e3e1f8a51218827168cdclaireho else 60805569331642446be05292e3e1f8a51218827168cdclaireho retError = error; 60815569331642446be05292e3e1f8a51218827168cdclaireho } 60825569331642446be05292e3e1f8a51218827168cdclaireho } 60835569331642446be05292e3e1f8a51218827168cdclaireho 60845569331642446be05292e3e1f8a51218827168cdclaireho if ( num_features ) 60855569331642446be05292e3e1f8a51218827168cdclaireho { 60865569331642446be05292e3e1f8a51218827168cdclaireho error = Position_CursiveChain ( buffer ); 60875569331642446be05292e3e1f8a51218827168cdclaireho if ( error ) 60885569331642446be05292e3e1f8a51218827168cdclaireho return error; 60895569331642446be05292e3e1f8a51218827168cdclaireho } 60905569331642446be05292e3e1f8a51218827168cdclaireho 60915569331642446be05292e3e1f8a51218827168cdclaireho return retError; 60925569331642446be05292e3e1f8a51218827168cdclaireho} 60935569331642446be05292e3e1f8a51218827168cdclaireho 60945569331642446be05292e3e1f8a51218827168cdclaireho/* END */ 6095