1*37da2899SCharles.Forsyth /***************************************************************************/ 2*37da2899SCharles.Forsyth /* */ 3*37da2899SCharles.Forsyth /* t1gload.c */ 4*37da2899SCharles.Forsyth /* */ 5*37da2899SCharles.Forsyth /* Type 1 Glyph Loader (body). */ 6*37da2899SCharles.Forsyth /* */ 7*37da2899SCharles.Forsyth /* Copyright 1996-2001, 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 <ft2build.h> 20*37da2899SCharles.Forsyth #include "t1gload.h" 21*37da2899SCharles.Forsyth #include FT_INTERNAL_DEBUG_H 22*37da2899SCharles.Forsyth #include FT_INTERNAL_STREAM_H 23*37da2899SCharles.Forsyth #include FT_OUTLINE_H 24*37da2899SCharles.Forsyth #include FT_INTERNAL_POSTSCRIPT_AUX_H 25*37da2899SCharles.Forsyth 26*37da2899SCharles.Forsyth #include "t1errors.h" 27*37da2899SCharles.Forsyth 28*37da2899SCharles.Forsyth 29*37da2899SCharles.Forsyth /*************************************************************************/ 30*37da2899SCharles.Forsyth /* */ 31*37da2899SCharles.Forsyth /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 32*37da2899SCharles.Forsyth /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 33*37da2899SCharles.Forsyth /* messages during execution. */ 34*37da2899SCharles.Forsyth /* */ 35*37da2899SCharles.Forsyth #undef FT_COMPONENT 36*37da2899SCharles.Forsyth #define FT_COMPONENT trace_t1gload 37*37da2899SCharles.Forsyth 38*37da2899SCharles.Forsyth 39*37da2899SCharles.Forsyth /*************************************************************************/ 40*37da2899SCharles.Forsyth /*************************************************************************/ 41*37da2899SCharles.Forsyth /*************************************************************************/ 42*37da2899SCharles.Forsyth /********** *********/ 43*37da2899SCharles.Forsyth /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/ 44*37da2899SCharles.Forsyth /********** *********/ 45*37da2899SCharles.Forsyth /********** The following code is in charge of computing *********/ 46*37da2899SCharles.Forsyth /********** the maximum advance width of the font. It *********/ 47*37da2899SCharles.Forsyth /********** quickly processes each glyph charstring to *********/ 48*37da2899SCharles.Forsyth /********** extract the value from either a `sbw' or `seac' *********/ 49*37da2899SCharles.Forsyth /********** operator. *********/ 50*37da2899SCharles.Forsyth /********** *********/ 51*37da2899SCharles.Forsyth /*************************************************************************/ 52*37da2899SCharles.Forsyth /*************************************************************************/ 53*37da2899SCharles.Forsyth /*************************************************************************/ 54*37da2899SCharles.Forsyth 55*37da2899SCharles.Forsyth 56*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) T1_Parse_Glyph_And_Get_Char_String(T1_Decoder decoder,FT_UInt glyph_index,FT_Data * char_string)57*37da2899SCharles.Forsyth T1_Parse_Glyph_And_Get_Char_String( T1_Decoder decoder, 58*37da2899SCharles.Forsyth FT_UInt glyph_index, 59*37da2899SCharles.Forsyth FT_Data* char_string ) 60*37da2899SCharles.Forsyth { 61*37da2899SCharles.Forsyth T1_Face face = (T1_Face)decoder->builder.face; 62*37da2899SCharles.Forsyth T1_Font type1 = &face->type1; 63*37da2899SCharles.Forsyth FT_Error error = 0; 64*37da2899SCharles.Forsyth 65*37da2899SCharles.Forsyth 66*37da2899SCharles.Forsyth decoder->font_matrix = type1->font_matrix; 67*37da2899SCharles.Forsyth decoder->font_offset = type1->font_offset; 68*37da2899SCharles.Forsyth 69*37da2899SCharles.Forsyth #ifdef FT_CONFIG_OPTION_INCREMENTAL 70*37da2899SCharles.Forsyth 71*37da2899SCharles.Forsyth /* For incremental fonts get the character data using the */ 72*37da2899SCharles.Forsyth /* callback function. */ 73*37da2899SCharles.Forsyth if ( face->root.internal->incremental_interface ) 74*37da2899SCharles.Forsyth error = face->root.internal->incremental_interface->funcs->get_glyph_data( 75*37da2899SCharles.Forsyth face->root.internal->incremental_interface->object, 76*37da2899SCharles.Forsyth glyph_index, char_string ); 77*37da2899SCharles.Forsyth else 78*37da2899SCharles.Forsyth 79*37da2899SCharles.Forsyth #endif 80*37da2899SCharles.Forsyth 81*37da2899SCharles.Forsyth /* For ordinary fonts get the character data stored in the face record. */ 82*37da2899SCharles.Forsyth { 83*37da2899SCharles.Forsyth char_string->pointer = type1->charstrings[glyph_index]; 84*37da2899SCharles.Forsyth char_string->length = type1->charstrings_len[glyph_index]; 85*37da2899SCharles.Forsyth } 86*37da2899SCharles.Forsyth 87*37da2899SCharles.Forsyth if ( !error ) 88*37da2899SCharles.Forsyth error = decoder->funcs.parse_charstrings( 89*37da2899SCharles.Forsyth decoder, (FT_Byte*)char_string->pointer, 90*37da2899SCharles.Forsyth char_string->length ); 91*37da2899SCharles.Forsyth 92*37da2899SCharles.Forsyth #ifdef FT_CONFIG_OPTION_INCREMENTAL 93*37da2899SCharles.Forsyth 94*37da2899SCharles.Forsyth /* Incremental fonts can optionally override the metrics. */ 95*37da2899SCharles.Forsyth if ( !error && face->root.internal->incremental_interface && 96*37da2899SCharles.Forsyth face->root.internal->incremental_interface->funcs->get_glyph_metrics ) 97*37da2899SCharles.Forsyth { 98*37da2899SCharles.Forsyth FT_Bool found = FALSE; 99*37da2899SCharles.Forsyth FT_Incremental_MetricsRec metrics; 100*37da2899SCharles.Forsyth 101*37da2899SCharles.Forsyth 102*37da2899SCharles.Forsyth error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( 103*37da2899SCharles.Forsyth face->root.internal->incremental_interface->object, 104*37da2899SCharles.Forsyth glyph_index, FALSE, &metrics, &found ); 105*37da2899SCharles.Forsyth if ( found ) 106*37da2899SCharles.Forsyth { 107*37da2899SCharles.Forsyth decoder->builder.left_bearing.x = metrics.bearing_x; 108*37da2899SCharles.Forsyth decoder->builder.left_bearing.y = metrics.bearing_y; 109*37da2899SCharles.Forsyth decoder->builder.advance.x = metrics.advance; 110*37da2899SCharles.Forsyth decoder->builder.advance.y = 0; 111*37da2899SCharles.Forsyth } 112*37da2899SCharles.Forsyth } 113*37da2899SCharles.Forsyth 114*37da2899SCharles.Forsyth #endif 115*37da2899SCharles.Forsyth 116*37da2899SCharles.Forsyth return error; 117*37da2899SCharles.Forsyth } 118*37da2899SCharles.Forsyth 119*37da2899SCharles.Forsyth 120*37da2899SCharles.Forsyth FT_CALLBACK_DEF( FT_Error ) T1_Parse_Glyph(T1_Decoder decoder,FT_UInt glyph_index)121*37da2899SCharles.Forsyth T1_Parse_Glyph( T1_Decoder decoder, 122*37da2899SCharles.Forsyth FT_UInt glyph_index ) 123*37da2899SCharles.Forsyth { 124*37da2899SCharles.Forsyth FT_Data glyph_data; 125*37da2899SCharles.Forsyth FT_Error error = T1_Parse_Glyph_And_Get_Char_String( 126*37da2899SCharles.Forsyth decoder, glyph_index, &glyph_data ); 127*37da2899SCharles.Forsyth 128*37da2899SCharles.Forsyth 129*37da2899SCharles.Forsyth #ifdef FT_CONFIG_OPTION_INCREMENTAL 130*37da2899SCharles.Forsyth if ( !error ) 131*37da2899SCharles.Forsyth { 132*37da2899SCharles.Forsyth T1_Face face = (T1_Face)decoder->builder.face; 133*37da2899SCharles.Forsyth 134*37da2899SCharles.Forsyth 135*37da2899SCharles.Forsyth if ( face->root.internal->incremental_interface ) 136*37da2899SCharles.Forsyth face->root.internal->incremental_interface->funcs->free_glyph_data( 137*37da2899SCharles.Forsyth face->root.internal->incremental_interface->object, 138*37da2899SCharles.Forsyth &glyph_data ); 139*37da2899SCharles.Forsyth } 140*37da2899SCharles.Forsyth #endif 141*37da2899SCharles.Forsyth 142*37da2899SCharles.Forsyth return error; 143*37da2899SCharles.Forsyth } 144*37da2899SCharles.Forsyth 145*37da2899SCharles.Forsyth 146*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) T1_Compute_Max_Advance(T1_Face face,FT_Int * max_advance)147*37da2899SCharles.Forsyth T1_Compute_Max_Advance( T1_Face face, 148*37da2899SCharles.Forsyth FT_Int* max_advance ) 149*37da2899SCharles.Forsyth { 150*37da2899SCharles.Forsyth FT_Error error; 151*37da2899SCharles.Forsyth T1_DecoderRec decoder; 152*37da2899SCharles.Forsyth FT_Int glyph_index; 153*37da2899SCharles.Forsyth T1_Font type1 = &face->type1; 154*37da2899SCharles.Forsyth PSAux_Service psaux = (PSAux_Service)face->psaux; 155*37da2899SCharles.Forsyth 156*37da2899SCharles.Forsyth 157*37da2899SCharles.Forsyth *max_advance = 0; 158*37da2899SCharles.Forsyth 159*37da2899SCharles.Forsyth /* initialize load decoder */ 160*37da2899SCharles.Forsyth error = psaux->t1_decoder_funcs->init( &decoder, 161*37da2899SCharles.Forsyth (FT_Face)face, 162*37da2899SCharles.Forsyth 0, /* size */ 163*37da2899SCharles.Forsyth 0, /* glyph slot */ 164*37da2899SCharles.Forsyth (FT_Byte**)type1->glyph_names, 165*37da2899SCharles.Forsyth face->blend, 166*37da2899SCharles.Forsyth 0, 167*37da2899SCharles.Forsyth FT_RENDER_MODE_NORMAL, 168*37da2899SCharles.Forsyth T1_Parse_Glyph ); 169*37da2899SCharles.Forsyth if ( error ) 170*37da2899SCharles.Forsyth return error; 171*37da2899SCharles.Forsyth 172*37da2899SCharles.Forsyth decoder.builder.metrics_only = 1; 173*37da2899SCharles.Forsyth decoder.builder.load_points = 0; 174*37da2899SCharles.Forsyth 175*37da2899SCharles.Forsyth decoder.num_subrs = type1->num_subrs; 176*37da2899SCharles.Forsyth decoder.subrs = type1->subrs; 177*37da2899SCharles.Forsyth decoder.subrs_len = type1->subrs_len; 178*37da2899SCharles.Forsyth 179*37da2899SCharles.Forsyth *max_advance = 0; 180*37da2899SCharles.Forsyth 181*37da2899SCharles.Forsyth /* for each glyph, parse the glyph charstring and extract */ 182*37da2899SCharles.Forsyth /* the advance width */ 183*37da2899SCharles.Forsyth for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ ) 184*37da2899SCharles.Forsyth { 185*37da2899SCharles.Forsyth /* now get load the unscaled outline */ 186*37da2899SCharles.Forsyth error = T1_Parse_Glyph( &decoder, glyph_index ); 187*37da2899SCharles.Forsyth if ( glyph_index == 0 || decoder.builder.advance.x > *max_advance ) 188*37da2899SCharles.Forsyth *max_advance = decoder.builder.advance.x; 189*37da2899SCharles.Forsyth 190*37da2899SCharles.Forsyth /* ignore the error if one occured - skip to next glyph */ 191*37da2899SCharles.Forsyth } 192*37da2899SCharles.Forsyth 193*37da2899SCharles.Forsyth return T1_Err_Ok; 194*37da2899SCharles.Forsyth } 195*37da2899SCharles.Forsyth 196*37da2899SCharles.Forsyth 197*37da2899SCharles.Forsyth /*************************************************************************/ 198*37da2899SCharles.Forsyth /*************************************************************************/ 199*37da2899SCharles.Forsyth /*************************************************************************/ 200*37da2899SCharles.Forsyth /********** *********/ 201*37da2899SCharles.Forsyth /********** UNHINTED GLYPH LOADER *********/ 202*37da2899SCharles.Forsyth /********** *********/ 203*37da2899SCharles.Forsyth /********** The following code is in charge of loading a *********/ 204*37da2899SCharles.Forsyth /********** single outline. It completely ignores hinting *********/ 205*37da2899SCharles.Forsyth /********** and is used when FT_LOAD_NO_HINTING is set. *********/ 206*37da2899SCharles.Forsyth /********** *********/ 207*37da2899SCharles.Forsyth /********** The Type 1 hinter is located in `t1hint.c' *********/ 208*37da2899SCharles.Forsyth /********** *********/ 209*37da2899SCharles.Forsyth /*************************************************************************/ 210*37da2899SCharles.Forsyth /*************************************************************************/ 211*37da2899SCharles.Forsyth /*************************************************************************/ 212*37da2899SCharles.Forsyth 213*37da2899SCharles.Forsyth 214*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) T1_Load_Glyph(T1_GlyphSlot glyph,T1_Size size,FT_UInt glyph_index,FT_Int32 load_flags)215*37da2899SCharles.Forsyth T1_Load_Glyph( T1_GlyphSlot glyph, 216*37da2899SCharles.Forsyth T1_Size size, 217*37da2899SCharles.Forsyth FT_UInt glyph_index, 218*37da2899SCharles.Forsyth FT_Int32 load_flags ) 219*37da2899SCharles.Forsyth { 220*37da2899SCharles.Forsyth FT_Error error; 221*37da2899SCharles.Forsyth T1_DecoderRec decoder; 222*37da2899SCharles.Forsyth T1_Face face = (T1_Face)glyph->root.face; 223*37da2899SCharles.Forsyth FT_Bool hinting; 224*37da2899SCharles.Forsyth T1_Font type1 = &face->type1; 225*37da2899SCharles.Forsyth PSAux_Service psaux = (PSAux_Service)face->psaux; 226*37da2899SCharles.Forsyth const T1_Decoder_Funcs decoder_funcs = psaux->t1_decoder_funcs; 227*37da2899SCharles.Forsyth 228*37da2899SCharles.Forsyth FT_Matrix font_matrix; 229*37da2899SCharles.Forsyth FT_Vector font_offset; 230*37da2899SCharles.Forsyth FT_Data glyph_data; 231*37da2899SCharles.Forsyth FT_Bool glyph_data_loaded = 0; 232*37da2899SCharles.Forsyth 233*37da2899SCharles.Forsyth 234*37da2899SCharles.Forsyth if ( load_flags & FT_LOAD_NO_RECURSE ) 235*37da2899SCharles.Forsyth load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; 236*37da2899SCharles.Forsyth 237*37da2899SCharles.Forsyth glyph->x_scale = size->root.metrics.x_scale; 238*37da2899SCharles.Forsyth glyph->y_scale = size->root.metrics.y_scale; 239*37da2899SCharles.Forsyth 240*37da2899SCharles.Forsyth glyph->root.outline.n_points = 0; 241*37da2899SCharles.Forsyth glyph->root.outline.n_contours = 0; 242*37da2899SCharles.Forsyth 243*37da2899SCharles.Forsyth hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 && 244*37da2899SCharles.Forsyth ( load_flags & FT_LOAD_NO_HINTING ) == 0 ); 245*37da2899SCharles.Forsyth 246*37da2899SCharles.Forsyth glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; 247*37da2899SCharles.Forsyth 248*37da2899SCharles.Forsyth error = decoder_funcs->init( &decoder, 249*37da2899SCharles.Forsyth (FT_Face)face, 250*37da2899SCharles.Forsyth (FT_Size)size, 251*37da2899SCharles.Forsyth (FT_GlyphSlot)glyph, 252*37da2899SCharles.Forsyth (FT_Byte**)type1->glyph_names, 253*37da2899SCharles.Forsyth face->blend, 254*37da2899SCharles.Forsyth FT_BOOL( hinting ), 255*37da2899SCharles.Forsyth FT_LOAD_TARGET_MODE(load_flags), 256*37da2899SCharles.Forsyth T1_Parse_Glyph ); 257*37da2899SCharles.Forsyth if ( error ) 258*37da2899SCharles.Forsyth goto Exit; 259*37da2899SCharles.Forsyth 260*37da2899SCharles.Forsyth decoder.builder.no_recurse = FT_BOOL( 261*37da2899SCharles.Forsyth ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ); 262*37da2899SCharles.Forsyth 263*37da2899SCharles.Forsyth decoder.num_subrs = type1->num_subrs; 264*37da2899SCharles.Forsyth decoder.subrs = type1->subrs; 265*37da2899SCharles.Forsyth decoder.subrs_len = type1->subrs_len; 266*37da2899SCharles.Forsyth 267*37da2899SCharles.Forsyth /* now load the unscaled outline */ 268*37da2899SCharles.Forsyth error = T1_Parse_Glyph_And_Get_Char_String( &decoder, glyph_index, 269*37da2899SCharles.Forsyth &glyph_data ); 270*37da2899SCharles.Forsyth if ( error ) 271*37da2899SCharles.Forsyth goto Exit; 272*37da2899SCharles.Forsyth glyph_data_loaded = 1; 273*37da2899SCharles.Forsyth 274*37da2899SCharles.Forsyth font_matrix = decoder.font_matrix; 275*37da2899SCharles.Forsyth font_offset = decoder.font_offset; 276*37da2899SCharles.Forsyth 277*37da2899SCharles.Forsyth /* save new glyph tables */ 278*37da2899SCharles.Forsyth decoder_funcs->done( &decoder ); 279*37da2899SCharles.Forsyth 280*37da2899SCharles.Forsyth /* now, set the metrics -- this is rather simple, as */ 281*37da2899SCharles.Forsyth /* the left side bearing is the xMin, and the top side */ 282*37da2899SCharles.Forsyth /* bearing the yMax */ 283*37da2899SCharles.Forsyth if ( !error ) 284*37da2899SCharles.Forsyth { 285*37da2899SCharles.Forsyth glyph->root.outline.flags &= FT_OUTLINE_OWNER; 286*37da2899SCharles.Forsyth glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL; 287*37da2899SCharles.Forsyth 288*37da2899SCharles.Forsyth /* for composite glyphs, return only left side bearing and */ 289*37da2899SCharles.Forsyth /* advance width */ 290*37da2899SCharles.Forsyth if ( load_flags & FT_LOAD_NO_RECURSE ) 291*37da2899SCharles.Forsyth { 292*37da2899SCharles.Forsyth FT_Slot_Internal internal = glyph->root.internal; 293*37da2899SCharles.Forsyth 294*37da2899SCharles.Forsyth 295*37da2899SCharles.Forsyth glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x; 296*37da2899SCharles.Forsyth glyph->root.metrics.horiAdvance = decoder.builder.advance.x; 297*37da2899SCharles.Forsyth internal->glyph_matrix = font_matrix; 298*37da2899SCharles.Forsyth internal->glyph_delta = font_offset; 299*37da2899SCharles.Forsyth internal->glyph_transformed = 1; 300*37da2899SCharles.Forsyth } 301*37da2899SCharles.Forsyth else 302*37da2899SCharles.Forsyth { 303*37da2899SCharles.Forsyth FT_BBox cbox; 304*37da2899SCharles.Forsyth FT_Glyph_Metrics* metrics = &glyph->root.metrics; 305*37da2899SCharles.Forsyth 306*37da2899SCharles.Forsyth 307*37da2899SCharles.Forsyth /* copy the _unscaled_ advance width */ 308*37da2899SCharles.Forsyth metrics->horiAdvance = decoder.builder.advance.x; 309*37da2899SCharles.Forsyth glyph->root.linearHoriAdvance = decoder.builder.advance.x; 310*37da2899SCharles.Forsyth glyph->root.internal->glyph_transformed = 0; 311*37da2899SCharles.Forsyth 312*37da2899SCharles.Forsyth /* make up vertical metrics */ 313*37da2899SCharles.Forsyth metrics->vertBearingX = 0; 314*37da2899SCharles.Forsyth metrics->vertBearingY = 0; 315*37da2899SCharles.Forsyth metrics->vertAdvance = 0; 316*37da2899SCharles.Forsyth 317*37da2899SCharles.Forsyth glyph->root.linearVertAdvance = 0; 318*37da2899SCharles.Forsyth 319*37da2899SCharles.Forsyth glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; 320*37da2899SCharles.Forsyth 321*37da2899SCharles.Forsyth if ( size && size->root.metrics.y_ppem < 24 ) 322*37da2899SCharles.Forsyth glyph->root.outline.flags |= FT_OUTLINE_HIGH_PRECISION; 323*37da2899SCharles.Forsyth 324*37da2899SCharles.Forsyth #if 1 325*37da2899SCharles.Forsyth /* apply the font matrix, if any */ 326*37da2899SCharles.Forsyth FT_Outline_Transform( &glyph->root.outline, &font_matrix ); 327*37da2899SCharles.Forsyth 328*37da2899SCharles.Forsyth FT_Outline_Translate( &glyph->root.outline, 329*37da2899SCharles.Forsyth font_offset.x, 330*37da2899SCharles.Forsyth font_offset.y ); 331*37da2899SCharles.Forsyth #endif 332*37da2899SCharles.Forsyth 333*37da2899SCharles.Forsyth if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) 334*37da2899SCharles.Forsyth { 335*37da2899SCharles.Forsyth /* scale the outline and the metrics */ 336*37da2899SCharles.Forsyth FT_Int n; 337*37da2899SCharles.Forsyth FT_Outline* cur = decoder.builder.base; 338*37da2899SCharles.Forsyth FT_Vector* vec = cur->points; 339*37da2899SCharles.Forsyth FT_Fixed x_scale = glyph->x_scale; 340*37da2899SCharles.Forsyth FT_Fixed y_scale = glyph->y_scale; 341*37da2899SCharles.Forsyth 342*37da2899SCharles.Forsyth 343*37da2899SCharles.Forsyth /* First of all, scale the points, if we are not hinting */ 344*37da2899SCharles.Forsyth if ( !hinting ) 345*37da2899SCharles.Forsyth for ( n = cur->n_points; n > 0; n--, vec++ ) 346*37da2899SCharles.Forsyth { 347*37da2899SCharles.Forsyth vec->x = FT_MulFix( vec->x, x_scale ); 348*37da2899SCharles.Forsyth vec->y = FT_MulFix( vec->y, y_scale ); 349*37da2899SCharles.Forsyth } 350*37da2899SCharles.Forsyth 351*37da2899SCharles.Forsyth FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); 352*37da2899SCharles.Forsyth 353*37da2899SCharles.Forsyth /* Then scale the metrics */ 354*37da2899SCharles.Forsyth metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); 355*37da2899SCharles.Forsyth metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); 356*37da2899SCharles.Forsyth 357*37da2899SCharles.Forsyth metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale ); 358*37da2899SCharles.Forsyth metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale ); 359*37da2899SCharles.Forsyth 360*37da2899SCharles.Forsyth if ( hinting ) 361*37da2899SCharles.Forsyth { 362*37da2899SCharles.Forsyth metrics->horiAdvance = ( metrics->horiAdvance + 32 ) & -64; 363*37da2899SCharles.Forsyth metrics->vertAdvance = ( metrics->vertAdvance + 32 ) & -64; 364*37da2899SCharles.Forsyth 365*37da2899SCharles.Forsyth metrics->vertBearingX = ( metrics->vertBearingX + 32 ) & -64; 366*37da2899SCharles.Forsyth metrics->vertBearingY = ( metrics->vertBearingY + 32 ) & -64; 367*37da2899SCharles.Forsyth } 368*37da2899SCharles.Forsyth } 369*37da2899SCharles.Forsyth 370*37da2899SCharles.Forsyth /* compute the other metrics */ 371*37da2899SCharles.Forsyth FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); 372*37da2899SCharles.Forsyth 373*37da2899SCharles.Forsyth /* grid fit the bounding box if necessary */ 374*37da2899SCharles.Forsyth if ( hinting ) 375*37da2899SCharles.Forsyth { 376*37da2899SCharles.Forsyth cbox.xMin &= -64; 377*37da2899SCharles.Forsyth cbox.yMin &= -64; 378*37da2899SCharles.Forsyth cbox.xMax = ( cbox.xMax+63 ) & -64; 379*37da2899SCharles.Forsyth cbox.yMax = ( cbox.yMax+63 ) & -64; 380*37da2899SCharles.Forsyth } 381*37da2899SCharles.Forsyth 382*37da2899SCharles.Forsyth metrics->width = cbox.xMax - cbox.xMin; 383*37da2899SCharles.Forsyth metrics->height = cbox.yMax - cbox.yMin; 384*37da2899SCharles.Forsyth 385*37da2899SCharles.Forsyth metrics->horiBearingX = cbox.xMin; 386*37da2899SCharles.Forsyth metrics->horiBearingY = cbox.yMax; 387*37da2899SCharles.Forsyth } 388*37da2899SCharles.Forsyth 389*37da2899SCharles.Forsyth /* Set control data to the glyph charstrings. Note that this is */ 390*37da2899SCharles.Forsyth /* _not_ zero-terminated. */ 391*37da2899SCharles.Forsyth glyph->root.control_data = (FT_Byte*)glyph_data.pointer; 392*37da2899SCharles.Forsyth glyph->root.control_len = glyph_data.length; 393*37da2899SCharles.Forsyth } 394*37da2899SCharles.Forsyth 395*37da2899SCharles.Forsyth 396*37da2899SCharles.Forsyth Exit: 397*37da2899SCharles.Forsyth 398*37da2899SCharles.Forsyth #ifdef FT_CONFIG_OPTION_INCREMENTAL 399*37da2899SCharles.Forsyth if ( glyph_data_loaded && face->root.internal->incremental_interface ) 400*37da2899SCharles.Forsyth { 401*37da2899SCharles.Forsyth face->root.internal->incremental_interface->funcs->free_glyph_data( 402*37da2899SCharles.Forsyth face->root.internal->incremental_interface->object, 403*37da2899SCharles.Forsyth &glyph_data ); 404*37da2899SCharles.Forsyth 405*37da2899SCharles.Forsyth /* Set the control data to null - it is no longer available if */ 406*37da2899SCharles.Forsyth /* loaded incrementally. */ 407*37da2899SCharles.Forsyth glyph->root.control_data = 0; 408*37da2899SCharles.Forsyth glyph->root.control_len = 0; 409*37da2899SCharles.Forsyth } 410*37da2899SCharles.Forsyth #endif 411*37da2899SCharles.Forsyth 412*37da2899SCharles.Forsyth return error; 413*37da2899SCharles.Forsyth } 414*37da2899SCharles.Forsyth 415*37da2899SCharles.Forsyth 416*37da2899SCharles.Forsyth /* END */ 417