1*37da2899SCharles.Forsyth /***************************************************************************/ 2*37da2899SCharles.Forsyth /* */ 3*37da2899SCharles.Forsyth /* pfrgload.c */ 4*37da2899SCharles.Forsyth /* */ 5*37da2899SCharles.Forsyth /* FreeType PFR glyph loader (body). */ 6*37da2899SCharles.Forsyth /* */ 7*37da2899SCharles.Forsyth /* Copyright 2002 by */ 8*37da2899SCharles.Forsyth /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9*37da2899SCharles.Forsyth /* */ 10*37da2899SCharles.Forsyth /* This file is part of the FreeType project, and may only be used, */ 11*37da2899SCharles.Forsyth /* modified, and distributed under the terms of the FreeType project */ 12*37da2899SCharles.Forsyth /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13*37da2899SCharles.Forsyth /* this file you indicate that you have read the license and */ 14*37da2899SCharles.Forsyth /* understand and accept it fully. */ 15*37da2899SCharles.Forsyth /* */ 16*37da2899SCharles.Forsyth /***************************************************************************/ 17*37da2899SCharles.Forsyth 18*37da2899SCharles.Forsyth 19*37da2899SCharles.Forsyth #include "pfrgload.h" 20*37da2899SCharles.Forsyth #include "pfrsbit.h" 21*37da2899SCharles.Forsyth #include "pfrload.h" /* for macro definitions */ 22*37da2899SCharles.Forsyth #include FT_INTERNAL_DEBUG_H 23*37da2899SCharles.Forsyth 24*37da2899SCharles.Forsyth #include "pfrerror.h" 25*37da2899SCharles.Forsyth 26*37da2899SCharles.Forsyth #undef FT_COMPONENT 27*37da2899SCharles.Forsyth #define FT_COMPONENT trace_pfr 28*37da2899SCharles.Forsyth 29*37da2899SCharles.Forsyth 30*37da2899SCharles.Forsyth /*************************************************************************/ 31*37da2899SCharles.Forsyth /*************************************************************************/ 32*37da2899SCharles.Forsyth /***** *****/ 33*37da2899SCharles.Forsyth /***** PFR GLYPH BUILDER *****/ 34*37da2899SCharles.Forsyth /***** *****/ 35*37da2899SCharles.Forsyth /*************************************************************************/ 36*37da2899SCharles.Forsyth /*************************************************************************/ 37*37da2899SCharles.Forsyth 38*37da2899SCharles.Forsyth 39*37da2899SCharles.Forsyth FT_LOCAL_DEF( void ) pfr_glyph_init(PFR_Glyph glyph,FT_GlyphLoader loader)40*37da2899SCharles.Forsyth pfr_glyph_init( PFR_Glyph glyph, 41*37da2899SCharles.Forsyth FT_GlyphLoader loader ) 42*37da2899SCharles.Forsyth { 43*37da2899SCharles.Forsyth FT_ZERO( glyph ); 44*37da2899SCharles.Forsyth 45*37da2899SCharles.Forsyth glyph->loader = loader; 46*37da2899SCharles.Forsyth glyph->path_begun = 0; 47*37da2899SCharles.Forsyth 48*37da2899SCharles.Forsyth FT_GlyphLoader_Rewind( loader ); 49*37da2899SCharles.Forsyth } 50*37da2899SCharles.Forsyth 51*37da2899SCharles.Forsyth 52*37da2899SCharles.Forsyth FT_LOCAL_DEF( void ) pfr_glyph_done(PFR_Glyph glyph)53*37da2899SCharles.Forsyth pfr_glyph_done( PFR_Glyph glyph ) 54*37da2899SCharles.Forsyth { 55*37da2899SCharles.Forsyth FT_Memory memory = glyph->loader->memory; 56*37da2899SCharles.Forsyth 57*37da2899SCharles.Forsyth 58*37da2899SCharles.Forsyth FT_FREE( glyph->x_control ); 59*37da2899SCharles.Forsyth glyph->y_control = NULL; 60*37da2899SCharles.Forsyth 61*37da2899SCharles.Forsyth glyph->max_xy_control = 0; 62*37da2899SCharles.Forsyth glyph->num_x_control = 0; 63*37da2899SCharles.Forsyth glyph->num_y_control = 0; 64*37da2899SCharles.Forsyth 65*37da2899SCharles.Forsyth FT_FREE( glyph->subs ); 66*37da2899SCharles.Forsyth 67*37da2899SCharles.Forsyth glyph->max_subs = 0; 68*37da2899SCharles.Forsyth glyph->num_subs = 0; 69*37da2899SCharles.Forsyth 70*37da2899SCharles.Forsyth glyph->loader = NULL; 71*37da2899SCharles.Forsyth glyph->path_begun = 0; 72*37da2899SCharles.Forsyth } 73*37da2899SCharles.Forsyth 74*37da2899SCharles.Forsyth 75*37da2899SCharles.Forsyth /* close current contour, if any */ 76*37da2899SCharles.Forsyth static void pfr_glyph_close_contour(PFR_Glyph glyph)77*37da2899SCharles.Forsyth pfr_glyph_close_contour( PFR_Glyph glyph ) 78*37da2899SCharles.Forsyth { 79*37da2899SCharles.Forsyth FT_GlyphLoader loader = glyph->loader; 80*37da2899SCharles.Forsyth FT_Outline* outline = &loader->current.outline; 81*37da2899SCharles.Forsyth FT_Int last, first; 82*37da2899SCharles.Forsyth 83*37da2899SCharles.Forsyth 84*37da2899SCharles.Forsyth if ( !glyph->path_begun ) 85*37da2899SCharles.Forsyth return; 86*37da2899SCharles.Forsyth 87*37da2899SCharles.Forsyth /* compute first and last point indices in current glyph outline */ 88*37da2899SCharles.Forsyth last = outline->n_points - 1; 89*37da2899SCharles.Forsyth first = 0; 90*37da2899SCharles.Forsyth if ( outline->n_contours > 0 ) 91*37da2899SCharles.Forsyth first = outline->contours[outline->n_contours - 1]; 92*37da2899SCharles.Forsyth 93*37da2899SCharles.Forsyth /* if the last point falls on the same location than the first one */ 94*37da2899SCharles.Forsyth /* we need to delete it */ 95*37da2899SCharles.Forsyth if ( last > first ) 96*37da2899SCharles.Forsyth { 97*37da2899SCharles.Forsyth FT_Vector* p1 = outline->points + first; 98*37da2899SCharles.Forsyth FT_Vector* p2 = outline->points + last; 99*37da2899SCharles.Forsyth 100*37da2899SCharles.Forsyth 101*37da2899SCharles.Forsyth if ( p1->x == p2->x && p1->y == p2->y ) 102*37da2899SCharles.Forsyth { 103*37da2899SCharles.Forsyth outline->n_points--; 104*37da2899SCharles.Forsyth last--; 105*37da2899SCharles.Forsyth } 106*37da2899SCharles.Forsyth } 107*37da2899SCharles.Forsyth 108*37da2899SCharles.Forsyth /* don't add empty contours */ 109*37da2899SCharles.Forsyth if ( last >= first ) 110*37da2899SCharles.Forsyth outline->contours[outline->n_contours++] = (short)last; 111*37da2899SCharles.Forsyth 112*37da2899SCharles.Forsyth glyph->path_begun = 0; 113*37da2899SCharles.Forsyth } 114*37da2899SCharles.Forsyth 115*37da2899SCharles.Forsyth 116*37da2899SCharles.Forsyth /* reset glyph to start the loading of a new glyph */ 117*37da2899SCharles.Forsyth static void pfr_glyph_start(PFR_Glyph glyph)118*37da2899SCharles.Forsyth pfr_glyph_start( PFR_Glyph glyph ) 119*37da2899SCharles.Forsyth { 120*37da2899SCharles.Forsyth glyph->path_begun = 0; 121*37da2899SCharles.Forsyth } 122*37da2899SCharles.Forsyth 123*37da2899SCharles.Forsyth 124*37da2899SCharles.Forsyth static FT_Error pfr_glyph_line_to(PFR_Glyph glyph,FT_Vector * to)125*37da2899SCharles.Forsyth pfr_glyph_line_to( PFR_Glyph glyph, 126*37da2899SCharles.Forsyth FT_Vector* to ) 127*37da2899SCharles.Forsyth { 128*37da2899SCharles.Forsyth FT_GlyphLoader loader = glyph->loader; 129*37da2899SCharles.Forsyth FT_Outline* outline = &loader->current.outline; 130*37da2899SCharles.Forsyth FT_Error error; 131*37da2899SCharles.Forsyth 132*37da2899SCharles.Forsyth 133*37da2899SCharles.Forsyth /* check that we have begun a new path */ 134*37da2899SCharles.Forsyth FT_ASSERT( glyph->path_begun != 0 ); 135*37da2899SCharles.Forsyth 136*37da2899SCharles.Forsyth error = FT_GlyphLoader_CheckPoints( loader, 1, 0 ); 137*37da2899SCharles.Forsyth if ( !error ) 138*37da2899SCharles.Forsyth { 139*37da2899SCharles.Forsyth FT_UInt n = outline->n_points; 140*37da2899SCharles.Forsyth 141*37da2899SCharles.Forsyth 142*37da2899SCharles.Forsyth outline->points[n] = *to; 143*37da2899SCharles.Forsyth outline->tags [n] = FT_CURVE_TAG_ON; 144*37da2899SCharles.Forsyth 145*37da2899SCharles.Forsyth outline->n_points++; 146*37da2899SCharles.Forsyth } 147*37da2899SCharles.Forsyth 148*37da2899SCharles.Forsyth return error; 149*37da2899SCharles.Forsyth } 150*37da2899SCharles.Forsyth 151*37da2899SCharles.Forsyth 152*37da2899SCharles.Forsyth static FT_Error pfr_glyph_curve_to(PFR_Glyph glyph,FT_Vector * control1,FT_Vector * control2,FT_Vector * to)153*37da2899SCharles.Forsyth pfr_glyph_curve_to( PFR_Glyph glyph, 154*37da2899SCharles.Forsyth FT_Vector* control1, 155*37da2899SCharles.Forsyth FT_Vector* control2, 156*37da2899SCharles.Forsyth FT_Vector* to ) 157*37da2899SCharles.Forsyth { 158*37da2899SCharles.Forsyth FT_GlyphLoader loader = glyph->loader; 159*37da2899SCharles.Forsyth FT_Outline* outline = &loader->current.outline; 160*37da2899SCharles.Forsyth FT_Error error; 161*37da2899SCharles.Forsyth 162*37da2899SCharles.Forsyth 163*37da2899SCharles.Forsyth /* check that we have begun a new path */ 164*37da2899SCharles.Forsyth FT_ASSERT( glyph->path_begun != 0 ); 165*37da2899SCharles.Forsyth 166*37da2899SCharles.Forsyth error = FT_GlyphLoader_CheckPoints( loader, 3, 0 ); 167*37da2899SCharles.Forsyth if ( !error ) 168*37da2899SCharles.Forsyth { 169*37da2899SCharles.Forsyth FT_Vector* vec = outline->points + outline->n_points; 170*37da2899SCharles.Forsyth FT_Byte* tag = (FT_Byte*)outline->tags + outline->n_points; 171*37da2899SCharles.Forsyth 172*37da2899SCharles.Forsyth 173*37da2899SCharles.Forsyth vec[0] = *control1; 174*37da2899SCharles.Forsyth vec[1] = *control2; 175*37da2899SCharles.Forsyth vec[2] = *to; 176*37da2899SCharles.Forsyth tag[0] = FT_CURVE_TAG_CUBIC; 177*37da2899SCharles.Forsyth tag[1] = FT_CURVE_TAG_CUBIC; 178*37da2899SCharles.Forsyth tag[2] = FT_CURVE_TAG_ON; 179*37da2899SCharles.Forsyth 180*37da2899SCharles.Forsyth outline->n_points = (FT_Short)( outline->n_points + 3 ); 181*37da2899SCharles.Forsyth } 182*37da2899SCharles.Forsyth 183*37da2899SCharles.Forsyth return error; 184*37da2899SCharles.Forsyth } 185*37da2899SCharles.Forsyth 186*37da2899SCharles.Forsyth 187*37da2899SCharles.Forsyth static FT_Error pfr_glyph_move_to(PFR_Glyph glyph,FT_Vector * to)188*37da2899SCharles.Forsyth pfr_glyph_move_to( PFR_Glyph glyph, 189*37da2899SCharles.Forsyth FT_Vector* to ) 190*37da2899SCharles.Forsyth { 191*37da2899SCharles.Forsyth FT_GlyphLoader loader = glyph->loader; 192*37da2899SCharles.Forsyth FT_Error error; 193*37da2899SCharles.Forsyth 194*37da2899SCharles.Forsyth 195*37da2899SCharles.Forsyth /* close current contour if any */ 196*37da2899SCharles.Forsyth pfr_glyph_close_contour( glyph ); 197*37da2899SCharles.Forsyth 198*37da2899SCharles.Forsyth /* indicate that a new contour has started */ 199*37da2899SCharles.Forsyth glyph->path_begun = 1; 200*37da2899SCharles.Forsyth 201*37da2899SCharles.Forsyth /* check that there is room for a new contour and a new point */ 202*37da2899SCharles.Forsyth error = FT_GlyphLoader_CheckPoints( loader, 1, 1 ); 203*37da2899SCharles.Forsyth if ( !error ) 204*37da2899SCharles.Forsyth /* add new start point */ 205*37da2899SCharles.Forsyth error = pfr_glyph_line_to( glyph, to ); 206*37da2899SCharles.Forsyth 207*37da2899SCharles.Forsyth return error; 208*37da2899SCharles.Forsyth } 209*37da2899SCharles.Forsyth 210*37da2899SCharles.Forsyth 211*37da2899SCharles.Forsyth static void pfr_glyph_end(PFR_Glyph glyph)212*37da2899SCharles.Forsyth pfr_glyph_end( PFR_Glyph glyph ) 213*37da2899SCharles.Forsyth { 214*37da2899SCharles.Forsyth /* close current contour if any */ 215*37da2899SCharles.Forsyth pfr_glyph_close_contour( glyph ); 216*37da2899SCharles.Forsyth 217*37da2899SCharles.Forsyth /* merge the current glyph into the stack */ 218*37da2899SCharles.Forsyth FT_GlyphLoader_Add( glyph->loader ); 219*37da2899SCharles.Forsyth } 220*37da2899SCharles.Forsyth 221*37da2899SCharles.Forsyth 222*37da2899SCharles.Forsyth /*************************************************************************/ 223*37da2899SCharles.Forsyth /*************************************************************************/ 224*37da2899SCharles.Forsyth /***** *****/ 225*37da2899SCharles.Forsyth /***** PFR GLYPH LOADER *****/ 226*37da2899SCharles.Forsyth /***** *****/ 227*37da2899SCharles.Forsyth /*************************************************************************/ 228*37da2899SCharles.Forsyth /*************************************************************************/ 229*37da2899SCharles.Forsyth 230*37da2899SCharles.Forsyth 231*37da2899SCharles.Forsyth /* load a simple glyph */ 232*37da2899SCharles.Forsyth static FT_Error pfr_glyph_load_simple(PFR_Glyph glyph,FT_Byte * p,FT_Byte * limit)233*37da2899SCharles.Forsyth pfr_glyph_load_simple( PFR_Glyph glyph, 234*37da2899SCharles.Forsyth FT_Byte* p, 235*37da2899SCharles.Forsyth FT_Byte* limit ) 236*37da2899SCharles.Forsyth { 237*37da2899SCharles.Forsyth FT_Error error = 0; 238*37da2899SCharles.Forsyth FT_Memory memory = glyph->loader->memory; 239*37da2899SCharles.Forsyth FT_UInt flags, x_count, y_count, i, count, mask; 240*37da2899SCharles.Forsyth FT_Int x; 241*37da2899SCharles.Forsyth 242*37da2899SCharles.Forsyth 243*37da2899SCharles.Forsyth PFR_CHECK( 1 ); 244*37da2899SCharles.Forsyth flags = PFR_NEXT_BYTE( p ); 245*37da2899SCharles.Forsyth 246*37da2899SCharles.Forsyth /* test for composite glyphs */ 247*37da2899SCharles.Forsyth FT_ASSERT( ( flags & PFR_GLYPH_IS_COMPOUND ) == 0 ); 248*37da2899SCharles.Forsyth 249*37da2899SCharles.Forsyth x_count = 0; 250*37da2899SCharles.Forsyth y_count = 0; 251*37da2899SCharles.Forsyth 252*37da2899SCharles.Forsyth if ( flags & PFR_GLYPH_1BYTE_XYCOUNT ) 253*37da2899SCharles.Forsyth { 254*37da2899SCharles.Forsyth PFR_CHECK( 1 ); 255*37da2899SCharles.Forsyth count = PFR_NEXT_BYTE( p ); 256*37da2899SCharles.Forsyth x_count = ( count & 15 ); 257*37da2899SCharles.Forsyth y_count = ( count >> 4 ); 258*37da2899SCharles.Forsyth } 259*37da2899SCharles.Forsyth else 260*37da2899SCharles.Forsyth { 261*37da2899SCharles.Forsyth if ( flags & PFR_GLYPH_XCOUNT ) 262*37da2899SCharles.Forsyth { 263*37da2899SCharles.Forsyth PFR_CHECK( 1 ); 264*37da2899SCharles.Forsyth x_count = PFR_NEXT_BYTE( p ); 265*37da2899SCharles.Forsyth } 266*37da2899SCharles.Forsyth 267*37da2899SCharles.Forsyth if ( flags & PFR_GLYPH_YCOUNT ) 268*37da2899SCharles.Forsyth { 269*37da2899SCharles.Forsyth PFR_CHECK( 1 ); 270*37da2899SCharles.Forsyth y_count = PFR_NEXT_BYTE( p ); 271*37da2899SCharles.Forsyth } 272*37da2899SCharles.Forsyth } 273*37da2899SCharles.Forsyth 274*37da2899SCharles.Forsyth count = x_count + y_count; 275*37da2899SCharles.Forsyth 276*37da2899SCharles.Forsyth /* re-allocate array when necessary */ 277*37da2899SCharles.Forsyth if ( count > glyph->max_xy_control ) 278*37da2899SCharles.Forsyth { 279*37da2899SCharles.Forsyth FT_UInt new_max = ( count + 7 ) & -8; 280*37da2899SCharles.Forsyth 281*37da2899SCharles.Forsyth 282*37da2899SCharles.Forsyth if ( FT_RENEW_ARRAY( glyph->x_control, 283*37da2899SCharles.Forsyth glyph->max_xy_control, 284*37da2899SCharles.Forsyth new_max ) ) 285*37da2899SCharles.Forsyth goto Exit; 286*37da2899SCharles.Forsyth 287*37da2899SCharles.Forsyth glyph->max_xy_control = new_max; 288*37da2899SCharles.Forsyth } 289*37da2899SCharles.Forsyth 290*37da2899SCharles.Forsyth glyph->y_control = glyph->x_control + x_count; 291*37da2899SCharles.Forsyth 292*37da2899SCharles.Forsyth mask = 0; 293*37da2899SCharles.Forsyth x = 0; 294*37da2899SCharles.Forsyth 295*37da2899SCharles.Forsyth for ( i = 0; i < count; i++ ) 296*37da2899SCharles.Forsyth { 297*37da2899SCharles.Forsyth if ( ( i & 7 ) == 0 ) 298*37da2899SCharles.Forsyth { 299*37da2899SCharles.Forsyth PFR_CHECK( 1 ); 300*37da2899SCharles.Forsyth mask = PFR_NEXT_BYTE( p ); 301*37da2899SCharles.Forsyth } 302*37da2899SCharles.Forsyth 303*37da2899SCharles.Forsyth if ( mask & 1 ) 304*37da2899SCharles.Forsyth { 305*37da2899SCharles.Forsyth PFR_CHECK( 2 ); 306*37da2899SCharles.Forsyth x = PFR_NEXT_SHORT( p ); 307*37da2899SCharles.Forsyth } 308*37da2899SCharles.Forsyth else 309*37da2899SCharles.Forsyth { 310*37da2899SCharles.Forsyth PFR_CHECK( 1 ); 311*37da2899SCharles.Forsyth x += PFR_NEXT_BYTE( p ); 312*37da2899SCharles.Forsyth } 313*37da2899SCharles.Forsyth 314*37da2899SCharles.Forsyth glyph->x_control[i] = x; 315*37da2899SCharles.Forsyth 316*37da2899SCharles.Forsyth mask >>= 1; 317*37da2899SCharles.Forsyth } 318*37da2899SCharles.Forsyth 319*37da2899SCharles.Forsyth /* XXX: for now we ignore the secondary stroke and edge definitions */ 320*37da2899SCharles.Forsyth /* since we don't want to support native PFR hinting */ 321*37da2899SCharles.Forsyth /* */ 322*37da2899SCharles.Forsyth if ( flags & PFR_GLYPH_EXTRA_ITEMS ) 323*37da2899SCharles.Forsyth { 324*37da2899SCharles.Forsyth error = pfr_extra_items_skip( &p, limit ); 325*37da2899SCharles.Forsyth if ( error ) 326*37da2899SCharles.Forsyth goto Exit; 327*37da2899SCharles.Forsyth } 328*37da2899SCharles.Forsyth 329*37da2899SCharles.Forsyth pfr_glyph_start( glyph ); 330*37da2899SCharles.Forsyth 331*37da2899SCharles.Forsyth /* now load a simple glyph */ 332*37da2899SCharles.Forsyth { 333*37da2899SCharles.Forsyth FT_Vector pos[4]; 334*37da2899SCharles.Forsyth FT_Vector* cur; 335*37da2899SCharles.Forsyth 336*37da2899SCharles.Forsyth 337*37da2899SCharles.Forsyth pos[0].x = pos[0].y = 0; 338*37da2899SCharles.Forsyth pos[3] = pos[0]; 339*37da2899SCharles.Forsyth 340*37da2899SCharles.Forsyth for (;;) 341*37da2899SCharles.Forsyth { 342*37da2899SCharles.Forsyth FT_Int format, args_format = 0, args_count, n; 343*37da2899SCharles.Forsyth 344*37da2899SCharles.Forsyth 345*37da2899SCharles.Forsyth /***************************************************************/ 346*37da2899SCharles.Forsyth /* read instruction */ 347*37da2899SCharles.Forsyth /* */ 348*37da2899SCharles.Forsyth PFR_CHECK( 1 ); 349*37da2899SCharles.Forsyth format = PFR_NEXT_BYTE( p ); 350*37da2899SCharles.Forsyth 351*37da2899SCharles.Forsyth switch ( format >> 4 ) 352*37da2899SCharles.Forsyth { 353*37da2899SCharles.Forsyth case 0: /* end glyph */ 354*37da2899SCharles.Forsyth FT_TRACE6(( "- end glyph" )); 355*37da2899SCharles.Forsyth args_count = 0; 356*37da2899SCharles.Forsyth break; 357*37da2899SCharles.Forsyth 358*37da2899SCharles.Forsyth case 1: /* general line operation */ 359*37da2899SCharles.Forsyth FT_TRACE6(( "- general line" )); 360*37da2899SCharles.Forsyth goto Line1; 361*37da2899SCharles.Forsyth 362*37da2899SCharles.Forsyth case 4: /* move to inside contour */ 363*37da2899SCharles.Forsyth FT_TRACE6(( "- move to inside" )); 364*37da2899SCharles.Forsyth goto Line1; 365*37da2899SCharles.Forsyth 366*37da2899SCharles.Forsyth case 5: /* move to outside contour */ 367*37da2899SCharles.Forsyth FT_TRACE6(( "- move to outside" )); 368*37da2899SCharles.Forsyth Line1: 369*37da2899SCharles.Forsyth args_format = format & 15; 370*37da2899SCharles.Forsyth args_count = 1; 371*37da2899SCharles.Forsyth break; 372*37da2899SCharles.Forsyth 373*37da2899SCharles.Forsyth case 2: /* horizontal line to */ 374*37da2899SCharles.Forsyth FT_TRACE6(( "- horizontal line to cx.%d", format & 15 )); 375*37da2899SCharles.Forsyth pos[0].y = pos[3].y; 376*37da2899SCharles.Forsyth pos[0].x = glyph->x_control[format & 15]; 377*37da2899SCharles.Forsyth pos[3] = pos[0]; 378*37da2899SCharles.Forsyth args_count = 0; 379*37da2899SCharles.Forsyth break; 380*37da2899SCharles.Forsyth 381*37da2899SCharles.Forsyth case 3: /* vertical line to */ 382*37da2899SCharles.Forsyth FT_TRACE6(( "- vertical line to cy.%d", format & 15 )); 383*37da2899SCharles.Forsyth pos[0].x = pos[3].x; 384*37da2899SCharles.Forsyth pos[0].y = glyph->y_control[format & 15]; 385*37da2899SCharles.Forsyth pos[3] = pos[0]; 386*37da2899SCharles.Forsyth args_count = 0; 387*37da2899SCharles.Forsyth break; 388*37da2899SCharles.Forsyth 389*37da2899SCharles.Forsyth case 6: /* horizontal to vertical curve */ 390*37da2899SCharles.Forsyth FT_TRACE6(( "- hv curve " )); 391*37da2899SCharles.Forsyth args_format = 0xB8E; 392*37da2899SCharles.Forsyth args_count = 3; 393*37da2899SCharles.Forsyth break; 394*37da2899SCharles.Forsyth 395*37da2899SCharles.Forsyth case 7: /* vertical to horizontal curve */ 396*37da2899SCharles.Forsyth FT_TRACE6(( "- vh curve" )); 397*37da2899SCharles.Forsyth args_format = 0xE2B; 398*37da2899SCharles.Forsyth args_count = 3; 399*37da2899SCharles.Forsyth break; 400*37da2899SCharles.Forsyth 401*37da2899SCharles.Forsyth default: /* general curve to */ 402*37da2899SCharles.Forsyth FT_TRACE6(( "- general curve" )); 403*37da2899SCharles.Forsyth args_count = 4; 404*37da2899SCharles.Forsyth args_format = format & 15; 405*37da2899SCharles.Forsyth } 406*37da2899SCharles.Forsyth 407*37da2899SCharles.Forsyth /***********************************************************/ 408*37da2899SCharles.Forsyth /* now read arguments */ 409*37da2899SCharles.Forsyth /* */ 410*37da2899SCharles.Forsyth cur = pos; 411*37da2899SCharles.Forsyth for ( n = 0; n < args_count; n++ ) 412*37da2899SCharles.Forsyth { 413*37da2899SCharles.Forsyth FT_Int idx, delta; 414*37da2899SCharles.Forsyth 415*37da2899SCharles.Forsyth 416*37da2899SCharles.Forsyth /* read the X argument */ 417*37da2899SCharles.Forsyth switch ( args_format & 3 ) 418*37da2899SCharles.Forsyth { 419*37da2899SCharles.Forsyth case 0: /* 8-bit index */ 420*37da2899SCharles.Forsyth PFR_CHECK( 1 ); 421*37da2899SCharles.Forsyth idx = PFR_NEXT_BYTE( p ); 422*37da2899SCharles.Forsyth cur->x = glyph->x_control[idx]; 423*37da2899SCharles.Forsyth FT_TRACE7(( " cx#%d", idx )); 424*37da2899SCharles.Forsyth break; 425*37da2899SCharles.Forsyth 426*37da2899SCharles.Forsyth case 1: /* 16-bit value */ 427*37da2899SCharles.Forsyth PFR_CHECK( 2 ); 428*37da2899SCharles.Forsyth cur->x = PFR_NEXT_SHORT( p ); 429*37da2899SCharles.Forsyth FT_TRACE7(( " x.%d", cur->x )); 430*37da2899SCharles.Forsyth break; 431*37da2899SCharles.Forsyth 432*37da2899SCharles.Forsyth case 2: /* 8-bit delta */ 433*37da2899SCharles.Forsyth PFR_CHECK( 1 ); 434*37da2899SCharles.Forsyth delta = PFR_NEXT_INT8( p ); 435*37da2899SCharles.Forsyth cur->x = pos[3].x + delta; 436*37da2899SCharles.Forsyth FT_TRACE7(( " dx.%d", delta )); 437*37da2899SCharles.Forsyth break; 438*37da2899SCharles.Forsyth 439*37da2899SCharles.Forsyth default: 440*37da2899SCharles.Forsyth FT_TRACE7(( " |" )); 441*37da2899SCharles.Forsyth cur->x = pos[3].x; 442*37da2899SCharles.Forsyth } 443*37da2899SCharles.Forsyth 444*37da2899SCharles.Forsyth /* read the Y argument */ 445*37da2899SCharles.Forsyth switch ( ( args_format >> 2 ) & 3 ) 446*37da2899SCharles.Forsyth { 447*37da2899SCharles.Forsyth case 0: /* 8-bit index */ 448*37da2899SCharles.Forsyth PFR_CHECK( 1 ); 449*37da2899SCharles.Forsyth idx = PFR_NEXT_BYTE( p ); 450*37da2899SCharles.Forsyth cur->y = glyph->y_control[idx]; 451*37da2899SCharles.Forsyth FT_TRACE7(( " cy#%d", idx )); 452*37da2899SCharles.Forsyth break; 453*37da2899SCharles.Forsyth 454*37da2899SCharles.Forsyth case 1: /* 16-bit absolute value */ 455*37da2899SCharles.Forsyth PFR_CHECK( 2 ); 456*37da2899SCharles.Forsyth cur->y = PFR_NEXT_SHORT( p ); 457*37da2899SCharles.Forsyth FT_TRACE7(( " y.%d", cur->y )); 458*37da2899SCharles.Forsyth break; 459*37da2899SCharles.Forsyth 460*37da2899SCharles.Forsyth case 2: /* 8-bit delta */ 461*37da2899SCharles.Forsyth PFR_CHECK( 1 ); 462*37da2899SCharles.Forsyth delta = PFR_NEXT_INT8( p ); 463*37da2899SCharles.Forsyth cur->y = pos[3].y + delta; 464*37da2899SCharles.Forsyth FT_TRACE7(( " dy.%d", delta )); 465*37da2899SCharles.Forsyth break; 466*37da2899SCharles.Forsyth 467*37da2899SCharles.Forsyth default: 468*37da2899SCharles.Forsyth FT_TRACE7(( " -" )); 469*37da2899SCharles.Forsyth cur->y = pos[3].y; 470*37da2899SCharles.Forsyth } 471*37da2899SCharles.Forsyth 472*37da2899SCharles.Forsyth /* read the additional format flag for the general curve */ 473*37da2899SCharles.Forsyth if ( n == 0 && args_count == 4 ) 474*37da2899SCharles.Forsyth { 475*37da2899SCharles.Forsyth PFR_CHECK( 1 ); 476*37da2899SCharles.Forsyth args_format = PFR_NEXT_BYTE( p ); 477*37da2899SCharles.Forsyth args_count--; 478*37da2899SCharles.Forsyth } 479*37da2899SCharles.Forsyth else 480*37da2899SCharles.Forsyth args_format >>= 4; 481*37da2899SCharles.Forsyth 482*37da2899SCharles.Forsyth /* save the previous point */ 483*37da2899SCharles.Forsyth pos[3] = cur[0]; 484*37da2899SCharles.Forsyth cur++; 485*37da2899SCharles.Forsyth } 486*37da2899SCharles.Forsyth 487*37da2899SCharles.Forsyth FT_TRACE7(( "\n" )); 488*37da2899SCharles.Forsyth 489*37da2899SCharles.Forsyth /***********************************************************/ 490*37da2899SCharles.Forsyth /* finally, execute instruction */ 491*37da2899SCharles.Forsyth /* */ 492*37da2899SCharles.Forsyth switch ( format >> 4 ) 493*37da2899SCharles.Forsyth { 494*37da2899SCharles.Forsyth case 0: /* end glyph => EXIT */ 495*37da2899SCharles.Forsyth pfr_glyph_end( glyph ); 496*37da2899SCharles.Forsyth goto Exit; 497*37da2899SCharles.Forsyth 498*37da2899SCharles.Forsyth case 1: /* line operations */ 499*37da2899SCharles.Forsyth case 2: 500*37da2899SCharles.Forsyth case 3: 501*37da2899SCharles.Forsyth error = pfr_glyph_line_to( glyph, pos ); 502*37da2899SCharles.Forsyth goto Test_Error; 503*37da2899SCharles.Forsyth 504*37da2899SCharles.Forsyth case 4: /* move to inside contour */ 505*37da2899SCharles.Forsyth case 5: /* move to outside contour */ 506*37da2899SCharles.Forsyth error = pfr_glyph_move_to( glyph, pos ); 507*37da2899SCharles.Forsyth goto Test_Error; 508*37da2899SCharles.Forsyth 509*37da2899SCharles.Forsyth default: /* curve operations */ 510*37da2899SCharles.Forsyth error = pfr_glyph_curve_to( glyph, pos, pos + 1, pos + 2 ); 511*37da2899SCharles.Forsyth 512*37da2899SCharles.Forsyth Test_Error: /* test error condition */ 513*37da2899SCharles.Forsyth if ( error ) 514*37da2899SCharles.Forsyth goto Exit; 515*37da2899SCharles.Forsyth } 516*37da2899SCharles.Forsyth } /* for (;;) */ 517*37da2899SCharles.Forsyth } 518*37da2899SCharles.Forsyth 519*37da2899SCharles.Forsyth Exit: 520*37da2899SCharles.Forsyth return error; 521*37da2899SCharles.Forsyth 522*37da2899SCharles.Forsyth Too_Short: 523*37da2899SCharles.Forsyth error = PFR_Err_Invalid_Table; 524*37da2899SCharles.Forsyth FT_ERROR(( "pfr_glyph_load_simple: invalid glyph data\n" )); 525*37da2899SCharles.Forsyth goto Exit; 526*37da2899SCharles.Forsyth } 527*37da2899SCharles.Forsyth 528*37da2899SCharles.Forsyth 529*37da2899SCharles.Forsyth /* load a composite/compound glyph */ 530*37da2899SCharles.Forsyth static FT_Error pfr_glyph_load_compound(PFR_Glyph glyph,FT_Byte * p,FT_Byte * limit)531*37da2899SCharles.Forsyth pfr_glyph_load_compound( PFR_Glyph glyph, 532*37da2899SCharles.Forsyth FT_Byte* p, 533*37da2899SCharles.Forsyth FT_Byte* limit ) 534*37da2899SCharles.Forsyth { 535*37da2899SCharles.Forsyth FT_Error error = 0; 536*37da2899SCharles.Forsyth FT_GlyphLoader loader = glyph->loader; 537*37da2899SCharles.Forsyth FT_Memory memory = loader->memory; 538*37da2899SCharles.Forsyth PFR_SubGlyph subglyph; 539*37da2899SCharles.Forsyth FT_UInt flags, i, count, org_count; 540*37da2899SCharles.Forsyth FT_Int x_pos, y_pos; 541*37da2899SCharles.Forsyth 542*37da2899SCharles.Forsyth 543*37da2899SCharles.Forsyth PFR_CHECK( 1 ); 544*37da2899SCharles.Forsyth flags = PFR_NEXT_BYTE( p ); 545*37da2899SCharles.Forsyth 546*37da2899SCharles.Forsyth /* test for composite glyphs */ 547*37da2899SCharles.Forsyth FT_ASSERT( ( flags & PFR_GLYPH_IS_COMPOUND ) != 0 ); 548*37da2899SCharles.Forsyth 549*37da2899SCharles.Forsyth count = flags & 0x3F; 550*37da2899SCharles.Forsyth 551*37da2899SCharles.Forsyth /* ignore extra items when present */ 552*37da2899SCharles.Forsyth /* */ 553*37da2899SCharles.Forsyth if ( flags & PFR_GLYPH_EXTRA_ITEMS ) 554*37da2899SCharles.Forsyth { 555*37da2899SCharles.Forsyth error = pfr_extra_items_skip( &p, limit ); 556*37da2899SCharles.Forsyth if (error) goto Exit; 557*37da2899SCharles.Forsyth } 558*37da2899SCharles.Forsyth 559*37da2899SCharles.Forsyth /* we can't rely on the FT_GlyphLoader to load sub-glyphs, because */ 560*37da2899SCharles.Forsyth /* the PFR format is dumb, using direct file offsets to point to the */ 561*37da2899SCharles.Forsyth /* sub-glyphs (instead of glyph indices). Sigh. */ 562*37da2899SCharles.Forsyth /* */ 563*37da2899SCharles.Forsyth /* For now, we load the list of sub-glyphs into a different array */ 564*37da2899SCharles.Forsyth /* but this will prevent us from using the auto-hinter at its best */ 565*37da2899SCharles.Forsyth /* quality. */ 566*37da2899SCharles.Forsyth /* */ 567*37da2899SCharles.Forsyth org_count = glyph->num_subs; 568*37da2899SCharles.Forsyth 569*37da2899SCharles.Forsyth if ( org_count + count > glyph->max_subs ) 570*37da2899SCharles.Forsyth { 571*37da2899SCharles.Forsyth FT_UInt new_max = ( org_count + count + 3 ) & -4; 572*37da2899SCharles.Forsyth 573*37da2899SCharles.Forsyth 574*37da2899SCharles.Forsyth if ( FT_RENEW_ARRAY( glyph->subs, glyph->max_subs, new_max ) ) 575*37da2899SCharles.Forsyth goto Exit; 576*37da2899SCharles.Forsyth 577*37da2899SCharles.Forsyth glyph->max_subs = new_max; 578*37da2899SCharles.Forsyth } 579*37da2899SCharles.Forsyth 580*37da2899SCharles.Forsyth subglyph = glyph->subs + org_count; 581*37da2899SCharles.Forsyth 582*37da2899SCharles.Forsyth for ( i = 0; i < count; i++, subglyph++ ) 583*37da2899SCharles.Forsyth { 584*37da2899SCharles.Forsyth FT_UInt format; 585*37da2899SCharles.Forsyth 586*37da2899SCharles.Forsyth 587*37da2899SCharles.Forsyth x_pos = 0; 588*37da2899SCharles.Forsyth y_pos = 0; 589*37da2899SCharles.Forsyth 590*37da2899SCharles.Forsyth PFR_CHECK( 1 ); 591*37da2899SCharles.Forsyth format = PFR_NEXT_BYTE( p ); 592*37da2899SCharles.Forsyth 593*37da2899SCharles.Forsyth /* read scale when available */ 594*37da2899SCharles.Forsyth subglyph->x_scale = 0x10000L; 595*37da2899SCharles.Forsyth if ( format & PFR_SUBGLYPH_XSCALE ) 596*37da2899SCharles.Forsyth { 597*37da2899SCharles.Forsyth PFR_CHECK( 2 ); 598*37da2899SCharles.Forsyth subglyph->x_scale = PFR_NEXT_SHORT( p ) << 4; 599*37da2899SCharles.Forsyth } 600*37da2899SCharles.Forsyth 601*37da2899SCharles.Forsyth subglyph->y_scale = 0x10000L; 602*37da2899SCharles.Forsyth if ( format & PFR_SUBGLYPH_YSCALE ) 603*37da2899SCharles.Forsyth { 604*37da2899SCharles.Forsyth PFR_CHECK( 2 ); 605*37da2899SCharles.Forsyth subglyph->y_scale = PFR_NEXT_SHORT( p ) << 4; 606*37da2899SCharles.Forsyth } 607*37da2899SCharles.Forsyth 608*37da2899SCharles.Forsyth /* read offset */ 609*37da2899SCharles.Forsyth switch ( format & 3 ) 610*37da2899SCharles.Forsyth { 611*37da2899SCharles.Forsyth case 1: 612*37da2899SCharles.Forsyth PFR_CHECK( 2 ); 613*37da2899SCharles.Forsyth x_pos = PFR_NEXT_SHORT( p ); 614*37da2899SCharles.Forsyth break; 615*37da2899SCharles.Forsyth 616*37da2899SCharles.Forsyth case 2: 617*37da2899SCharles.Forsyth PFR_CHECK( 1 ); 618*37da2899SCharles.Forsyth x_pos += PFR_NEXT_INT8( p ); 619*37da2899SCharles.Forsyth break; 620*37da2899SCharles.Forsyth 621*37da2899SCharles.Forsyth default: 622*37da2899SCharles.Forsyth ; 623*37da2899SCharles.Forsyth } 624*37da2899SCharles.Forsyth 625*37da2899SCharles.Forsyth switch ( ( format >> 2 ) & 3 ) 626*37da2899SCharles.Forsyth { 627*37da2899SCharles.Forsyth case 1: 628*37da2899SCharles.Forsyth PFR_CHECK( 2 ); 629*37da2899SCharles.Forsyth y_pos = PFR_NEXT_SHORT( p ); 630*37da2899SCharles.Forsyth break; 631*37da2899SCharles.Forsyth 632*37da2899SCharles.Forsyth case 2: 633*37da2899SCharles.Forsyth PFR_CHECK( 1 ); 634*37da2899SCharles.Forsyth y_pos += PFR_NEXT_INT8( p ); 635*37da2899SCharles.Forsyth break; 636*37da2899SCharles.Forsyth 637*37da2899SCharles.Forsyth default: 638*37da2899SCharles.Forsyth ; 639*37da2899SCharles.Forsyth } 640*37da2899SCharles.Forsyth 641*37da2899SCharles.Forsyth subglyph->x_delta = x_pos; 642*37da2899SCharles.Forsyth subglyph->y_delta = y_pos; 643*37da2899SCharles.Forsyth 644*37da2899SCharles.Forsyth /* read glyph position and size now */ 645*37da2899SCharles.Forsyth if ( format & PFR_SUBGLYPH_2BYTE_SIZE ) 646*37da2899SCharles.Forsyth { 647*37da2899SCharles.Forsyth PFR_CHECK( 2 ); 648*37da2899SCharles.Forsyth subglyph->gps_size = PFR_NEXT_USHORT( p ); 649*37da2899SCharles.Forsyth } 650*37da2899SCharles.Forsyth else 651*37da2899SCharles.Forsyth { 652*37da2899SCharles.Forsyth PFR_CHECK( 1 ); 653*37da2899SCharles.Forsyth subglyph->gps_size = PFR_NEXT_BYTE( p ); 654*37da2899SCharles.Forsyth } 655*37da2899SCharles.Forsyth 656*37da2899SCharles.Forsyth if ( format & PFR_SUBGLYPH_3BYTE_OFFSET ) 657*37da2899SCharles.Forsyth { 658*37da2899SCharles.Forsyth PFR_CHECK( 3 ); 659*37da2899SCharles.Forsyth subglyph->gps_offset = PFR_NEXT_LONG( p ); 660*37da2899SCharles.Forsyth } 661*37da2899SCharles.Forsyth else 662*37da2899SCharles.Forsyth { 663*37da2899SCharles.Forsyth PFR_CHECK( 2 ); 664*37da2899SCharles.Forsyth subglyph->gps_offset = PFR_NEXT_USHORT( p ); 665*37da2899SCharles.Forsyth } 666*37da2899SCharles.Forsyth 667*37da2899SCharles.Forsyth glyph->num_subs++; 668*37da2899SCharles.Forsyth } 669*37da2899SCharles.Forsyth 670*37da2899SCharles.Forsyth Exit: 671*37da2899SCharles.Forsyth return error; 672*37da2899SCharles.Forsyth 673*37da2899SCharles.Forsyth Too_Short: 674*37da2899SCharles.Forsyth error = PFR_Err_Invalid_Table; 675*37da2899SCharles.Forsyth FT_ERROR(( "pfr_glyph_load_compound: invalid glyph data\n" )); 676*37da2899SCharles.Forsyth goto Exit; 677*37da2899SCharles.Forsyth } 678*37da2899SCharles.Forsyth 679*37da2899SCharles.Forsyth 680*37da2899SCharles.Forsyth 681*37da2899SCharles.Forsyth 682*37da2899SCharles.Forsyth 683*37da2899SCharles.Forsyth static FT_Error pfr_glyph_load_rec(PFR_Glyph glyph,FT_Stream stream,FT_ULong gps_offset,FT_ULong offset,FT_ULong size)684*37da2899SCharles.Forsyth pfr_glyph_load_rec( PFR_Glyph glyph, 685*37da2899SCharles.Forsyth FT_Stream stream, 686*37da2899SCharles.Forsyth FT_ULong gps_offset, 687*37da2899SCharles.Forsyth FT_ULong offset, 688*37da2899SCharles.Forsyth FT_ULong size ) 689*37da2899SCharles.Forsyth { 690*37da2899SCharles.Forsyth FT_Error error; 691*37da2899SCharles.Forsyth FT_Byte* p; 692*37da2899SCharles.Forsyth FT_Byte* limit; 693*37da2899SCharles.Forsyth 694*37da2899SCharles.Forsyth 695*37da2899SCharles.Forsyth if ( FT_STREAM_SEEK( gps_offset + offset ) || 696*37da2899SCharles.Forsyth FT_FRAME_ENTER( size ) ) 697*37da2899SCharles.Forsyth goto Exit; 698*37da2899SCharles.Forsyth 699*37da2899SCharles.Forsyth p = (FT_Byte*)stream->cursor; 700*37da2899SCharles.Forsyth limit = p + size; 701*37da2899SCharles.Forsyth 702*37da2899SCharles.Forsyth if ( size > 0 && *p & PFR_GLYPH_IS_COMPOUND ) 703*37da2899SCharles.Forsyth { 704*37da2899SCharles.Forsyth FT_Int n, old_count, count; 705*37da2899SCharles.Forsyth FT_GlyphLoader loader = glyph->loader; 706*37da2899SCharles.Forsyth FT_Outline* base = &loader->base.outline; 707*37da2899SCharles.Forsyth 708*37da2899SCharles.Forsyth 709*37da2899SCharles.Forsyth old_count = glyph->num_subs; 710*37da2899SCharles.Forsyth 711*37da2899SCharles.Forsyth /* this is a compound glyph - load it */ 712*37da2899SCharles.Forsyth error = pfr_glyph_load_compound( glyph, p, limit ); 713*37da2899SCharles.Forsyth 714*37da2899SCharles.Forsyth FT_FRAME_EXIT(); 715*37da2899SCharles.Forsyth 716*37da2899SCharles.Forsyth if ( error ) 717*37da2899SCharles.Forsyth goto Exit; 718*37da2899SCharles.Forsyth 719*37da2899SCharles.Forsyth count = glyph->num_subs - old_count; 720*37da2899SCharles.Forsyth 721*37da2899SCharles.Forsyth /* now, load each individual glyph */ 722*37da2899SCharles.Forsyth for ( n = 0; n < count; n++ ) 723*37da2899SCharles.Forsyth { 724*37da2899SCharles.Forsyth FT_Int i, old_points, num_points; 725*37da2899SCharles.Forsyth PFR_SubGlyph subglyph; 726*37da2899SCharles.Forsyth 727*37da2899SCharles.Forsyth 728*37da2899SCharles.Forsyth subglyph = glyph->subs + old_count + n; 729*37da2899SCharles.Forsyth old_points = base->n_points; 730*37da2899SCharles.Forsyth 731*37da2899SCharles.Forsyth error = pfr_glyph_load_rec( glyph, stream, gps_offset, 732*37da2899SCharles.Forsyth subglyph->gps_offset, 733*37da2899SCharles.Forsyth subglyph->gps_size ); 734*37da2899SCharles.Forsyth if ( error ) 735*37da2899SCharles.Forsyth goto Exit; 736*37da2899SCharles.Forsyth 737*37da2899SCharles.Forsyth /* note that `glyph->subs' might have been re-allocated */ 738*37da2899SCharles.Forsyth subglyph = glyph->subs + old_count + n; 739*37da2899SCharles.Forsyth num_points = base->n_points - old_points; 740*37da2899SCharles.Forsyth 741*37da2899SCharles.Forsyth /* translate and eventually scale the new glyph points */ 742*37da2899SCharles.Forsyth if ( subglyph->x_scale != 0x10000L || subglyph->y_scale != 0x10000L ) 743*37da2899SCharles.Forsyth { 744*37da2899SCharles.Forsyth FT_Vector* vec = base->points + old_points; 745*37da2899SCharles.Forsyth 746*37da2899SCharles.Forsyth 747*37da2899SCharles.Forsyth for ( i = 0; i < num_points; i++, vec++ ) 748*37da2899SCharles.Forsyth { 749*37da2899SCharles.Forsyth vec->x = FT_MulFix( vec->x, subglyph->x_scale ) + 750*37da2899SCharles.Forsyth subglyph->x_delta; 751*37da2899SCharles.Forsyth vec->y = FT_MulFix( vec->y, subglyph->y_scale ) + 752*37da2899SCharles.Forsyth subglyph->y_delta; 753*37da2899SCharles.Forsyth } 754*37da2899SCharles.Forsyth } 755*37da2899SCharles.Forsyth else 756*37da2899SCharles.Forsyth { 757*37da2899SCharles.Forsyth FT_Vector* vec = loader->base.outline.points + old_points; 758*37da2899SCharles.Forsyth 759*37da2899SCharles.Forsyth 760*37da2899SCharles.Forsyth for ( i = 0; i < num_points; i++, vec++ ) 761*37da2899SCharles.Forsyth { 762*37da2899SCharles.Forsyth vec->x += subglyph->x_delta; 763*37da2899SCharles.Forsyth vec->y += subglyph->y_delta; 764*37da2899SCharles.Forsyth } 765*37da2899SCharles.Forsyth } 766*37da2899SCharles.Forsyth 767*37da2899SCharles.Forsyth /* proceed to next sub-glyph */ 768*37da2899SCharles.Forsyth } 769*37da2899SCharles.Forsyth } 770*37da2899SCharles.Forsyth else 771*37da2899SCharles.Forsyth { 772*37da2899SCharles.Forsyth /* load a simple glyph */ 773*37da2899SCharles.Forsyth error = pfr_glyph_load_simple( glyph, p, limit ); 774*37da2899SCharles.Forsyth 775*37da2899SCharles.Forsyth FT_FRAME_EXIT(); 776*37da2899SCharles.Forsyth } 777*37da2899SCharles.Forsyth 778*37da2899SCharles.Forsyth Exit: 779*37da2899SCharles.Forsyth return error; 780*37da2899SCharles.Forsyth } 781*37da2899SCharles.Forsyth 782*37da2899SCharles.Forsyth 783*37da2899SCharles.Forsyth 784*37da2899SCharles.Forsyth 785*37da2899SCharles.Forsyth 786*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) pfr_glyph_load(PFR_Glyph glyph,FT_Stream stream,FT_ULong gps_offset,FT_ULong offset,FT_ULong size)787*37da2899SCharles.Forsyth pfr_glyph_load( PFR_Glyph glyph, 788*37da2899SCharles.Forsyth FT_Stream stream, 789*37da2899SCharles.Forsyth FT_ULong gps_offset, 790*37da2899SCharles.Forsyth FT_ULong offset, 791*37da2899SCharles.Forsyth FT_ULong size ) 792*37da2899SCharles.Forsyth { 793*37da2899SCharles.Forsyth /* initialize glyph loader */ 794*37da2899SCharles.Forsyth FT_GlyphLoader_Rewind( glyph->loader ); 795*37da2899SCharles.Forsyth 796*37da2899SCharles.Forsyth /* load the glyph, recursively when needed */ 797*37da2899SCharles.Forsyth return pfr_glyph_load_rec( glyph, stream, gps_offset, offset, size ); 798*37da2899SCharles.Forsyth } 799*37da2899SCharles.Forsyth 800*37da2899SCharles.Forsyth 801*37da2899SCharles.Forsyth /* END */ 802