| 1 | /**************************************************************************** | 
|---|
| 2 | * | 
|---|
| 3 | * t1gload.c | 
|---|
| 4 | * | 
|---|
| 5 | *   Type 1 Glyph Loader (body). | 
|---|
| 6 | * | 
|---|
| 7 | * Copyright (C) 1996-2019 by | 
|---|
| 8 | * David Turner, Robert Wilhelm, and Werner Lemberg. | 
|---|
| 9 | * | 
|---|
| 10 | * This file is part of the FreeType project, and may only be used, | 
|---|
| 11 | * modified, and distributed under the terms of the FreeType project | 
|---|
| 12 | * license, LICENSE.TXT.  By continuing to use, modify, or distribute | 
|---|
| 13 | * this file you indicate that you have read the license and | 
|---|
| 14 | * understand and accept it fully. | 
|---|
| 15 | * | 
|---|
| 16 | */ | 
|---|
| 17 |  | 
|---|
| 18 |  | 
|---|
| 19 | #include <ft2build.h> | 
|---|
| 20 | #include "t1gload.h" | 
|---|
| 21 | #include FT_INTERNAL_CALC_H | 
|---|
| 22 | #include FT_INTERNAL_DEBUG_H | 
|---|
| 23 | #include FT_INTERNAL_STREAM_H | 
|---|
| 24 | #include FT_OUTLINE_H | 
|---|
| 25 | #include FT_INTERNAL_POSTSCRIPT_AUX_H | 
|---|
| 26 | #include FT_INTERNAL_CFF_TYPES_H | 
|---|
| 27 | #include FT_DRIVER_H | 
|---|
| 28 |  | 
|---|
| 29 | #include "t1errors.h" | 
|---|
| 30 |  | 
|---|
| 31 |  | 
|---|
| 32 | /************************************************************************** | 
|---|
| 33 | * | 
|---|
| 34 | * The macro FT_COMPONENT is used in trace mode.  It is an implicit | 
|---|
| 35 | * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log | 
|---|
| 36 | * messages during execution. | 
|---|
| 37 | */ | 
|---|
| 38 | #undef  FT_COMPONENT | 
|---|
| 39 | #define FT_COMPONENT  t1gload | 
|---|
| 40 |  | 
|---|
| 41 |  | 
|---|
| 42 | static FT_Error | 
|---|
| 43 | T1_Parse_Glyph_And_Get_Char_String( T1_Decoder  decoder, | 
|---|
| 44 | FT_UInt     glyph_index, | 
|---|
| 45 | FT_Data*    char_string, | 
|---|
| 46 | FT_Bool*    force_scaling ) | 
|---|
| 47 | { | 
|---|
| 48 | T1_Face   face  = (T1_Face)decoder->builder.face; | 
|---|
| 49 | T1_Font   type1 = &face->type1; | 
|---|
| 50 | FT_Error  error = FT_Err_Ok; | 
|---|
| 51 |  | 
|---|
| 52 | PSAux_Service           psaux         = (PSAux_Service)face->psaux; | 
|---|
| 53 | const T1_Decoder_Funcs  decoder_funcs = psaux->t1_decoder_funcs; | 
|---|
| 54 | PS_Decoder              psdecoder; | 
|---|
| 55 |  | 
|---|
| 56 | #ifdef FT_CONFIG_OPTION_INCREMENTAL | 
|---|
| 57 | FT_Incremental_InterfaceRec *inc = | 
|---|
| 58 | face->root.internal->incremental_interface; | 
|---|
| 59 | #endif | 
|---|
| 60 |  | 
|---|
| 61 | #ifdef T1_CONFIG_OPTION_OLD_ENGINE | 
|---|
| 62 | PS_Driver  driver = (PS_Driver)FT_FACE_DRIVER( face ); | 
|---|
| 63 | #endif | 
|---|
| 64 |  | 
|---|
| 65 |  | 
|---|
| 66 | decoder->font_matrix = type1->font_matrix; | 
|---|
| 67 | decoder->font_offset = type1->font_offset; | 
|---|
| 68 |  | 
|---|
| 69 | #ifdef FT_CONFIG_OPTION_INCREMENTAL | 
|---|
| 70 |  | 
|---|
| 71 | /* For incremental fonts get the character data using the */ | 
|---|
| 72 | /* callback function.                                     */ | 
|---|
| 73 | if ( inc ) | 
|---|
| 74 | error = inc->funcs->get_glyph_data( inc->object, | 
|---|
| 75 | glyph_index, char_string ); | 
|---|
| 76 | else | 
|---|
| 77 |  | 
|---|
| 78 | #endif /* FT_CONFIG_OPTION_INCREMENTAL */ | 
|---|
| 79 |  | 
|---|
| 80 | /* For ordinary fonts get the character data stored in the face record. */ | 
|---|
| 81 | { | 
|---|
| 82 | char_string->pointer = type1->charstrings[glyph_index]; | 
|---|
| 83 | char_string->length  = (FT_Int)type1->charstrings_len[glyph_index]; | 
|---|
| 84 | } | 
|---|
| 85 |  | 
|---|
| 86 | if ( !error ) | 
|---|
| 87 | { | 
|---|
| 88 | /* choose which renderer to use */ | 
|---|
| 89 | #ifdef T1_CONFIG_OPTION_OLD_ENGINE | 
|---|
| 90 | if ( driver->hinting_engine == FT_HINTING_FREETYPE || | 
|---|
| 91 | decoder->builder.metrics_only                 ) | 
|---|
| 92 | error = decoder_funcs->parse_charstrings_old( | 
|---|
| 93 | decoder, | 
|---|
| 94 | (FT_Byte*)char_string->pointer, | 
|---|
| 95 | (FT_UInt)char_string->length ); | 
|---|
| 96 | #else | 
|---|
| 97 | if ( decoder->builder.metrics_only ) | 
|---|
| 98 | error = decoder_funcs->parse_metrics( | 
|---|
| 99 | decoder, | 
|---|
| 100 | (FT_Byte*)char_string->pointer, | 
|---|
| 101 | (FT_UInt)char_string->length ); | 
|---|
| 102 | #endif | 
|---|
| 103 | else | 
|---|
| 104 | { | 
|---|
| 105 | CFF_SubFontRec  subfont; | 
|---|
| 106 |  | 
|---|
| 107 |  | 
|---|
| 108 | psaux->ps_decoder_init( &psdecoder, decoder, TRUE ); | 
|---|
| 109 |  | 
|---|
| 110 | psaux->t1_make_subfont( FT_FACE( face ), | 
|---|
| 111 | &face->type1.private_dict, &subfont ); | 
|---|
| 112 | psdecoder.current_subfont = &subfont; | 
|---|
| 113 |  | 
|---|
| 114 | error = decoder_funcs->parse_charstrings( | 
|---|
| 115 | &psdecoder, | 
|---|
| 116 | (FT_Byte*)char_string->pointer, | 
|---|
| 117 | (FT_ULong)char_string->length ); | 
|---|
| 118 |  | 
|---|
| 119 | /* Adobe's engine uses 16.16 numbers everywhere;              */ | 
|---|
| 120 | /* as a consequence, glyphs larger than 2000ppem get rejected */ | 
|---|
| 121 | if ( FT_ERR_EQ( error, Glyph_Too_Big ) ) | 
|---|
| 122 | { | 
|---|
| 123 | /* this time, we retry unhinted and scale up the glyph later on */ | 
|---|
| 124 | /* (the engine uses and sets the hardcoded value 0x10000 / 64 = */ | 
|---|
| 125 | /* 0x400 for both `x_scale' and `y_scale' in this case)         */ | 
|---|
| 126 | ((T1_GlyphSlot)decoder->builder.glyph)->hint = FALSE; | 
|---|
| 127 |  | 
|---|
| 128 | *force_scaling = TRUE; | 
|---|
| 129 |  | 
|---|
| 130 | error = decoder_funcs->parse_charstrings( | 
|---|
| 131 | &psdecoder, | 
|---|
| 132 | (FT_Byte*)char_string->pointer, | 
|---|
| 133 | (FT_ULong)char_string->length ); | 
|---|
| 134 | } | 
|---|
| 135 | } | 
|---|
| 136 | } | 
|---|
| 137 |  | 
|---|
| 138 | #ifdef FT_CONFIG_OPTION_INCREMENTAL | 
|---|
| 139 |  | 
|---|
| 140 | /* Incremental fonts can optionally override the metrics. */ | 
|---|
| 141 | if ( !error && inc && inc->funcs->get_glyph_metrics ) | 
|---|
| 142 | { | 
|---|
| 143 | FT_Incremental_MetricsRec  metrics; | 
|---|
| 144 |  | 
|---|
| 145 |  | 
|---|
| 146 | metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x ); | 
|---|
| 147 | metrics.bearing_y = 0; | 
|---|
| 148 | metrics.advance   = FIXED_TO_INT( decoder->builder.advance.x ); | 
|---|
| 149 | metrics.advance_v = FIXED_TO_INT( decoder->builder.advance.y ); | 
|---|
| 150 |  | 
|---|
| 151 | error = inc->funcs->get_glyph_metrics( inc->object, | 
|---|
| 152 | glyph_index, FALSE, &metrics ); | 
|---|
| 153 |  | 
|---|
| 154 | decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x ); | 
|---|
| 155 | decoder->builder.advance.x      = INT_TO_FIXED( metrics.advance ); | 
|---|
| 156 | decoder->builder.advance.y      = INT_TO_FIXED( metrics.advance_v ); | 
|---|
| 157 | } | 
|---|
| 158 |  | 
|---|
| 159 | #endif /* FT_CONFIG_OPTION_INCREMENTAL */ | 
|---|
| 160 |  | 
|---|
| 161 | return error; | 
|---|
| 162 | } | 
|---|
| 163 |  | 
|---|
| 164 |  | 
|---|
| 165 | FT_CALLBACK_DEF( FT_Error ) | 
|---|
| 166 | T1_Parse_Glyph( T1_Decoder  decoder, | 
|---|
| 167 | FT_UInt     glyph_index ) | 
|---|
| 168 | { | 
|---|
| 169 | FT_Data   glyph_data; | 
|---|
| 170 | FT_Bool   force_scaling = FALSE; | 
|---|
| 171 | FT_Error  error         = T1_Parse_Glyph_And_Get_Char_String( | 
|---|
| 172 | decoder, glyph_index, &glyph_data, | 
|---|
| 173 | &force_scaling ); | 
|---|
| 174 |  | 
|---|
| 175 |  | 
|---|
| 176 | #ifdef FT_CONFIG_OPTION_INCREMENTAL | 
|---|
| 177 |  | 
|---|
| 178 | if ( !error ) | 
|---|
| 179 | { | 
|---|
| 180 | T1_Face  face = (T1_Face)decoder->builder.face; | 
|---|
| 181 |  | 
|---|
| 182 |  | 
|---|
| 183 | if ( face->root.internal->incremental_interface ) | 
|---|
| 184 | face->root.internal->incremental_interface->funcs->free_glyph_data( | 
|---|
| 185 | face->root.internal->incremental_interface->object, | 
|---|
| 186 | &glyph_data ); | 
|---|
| 187 | } | 
|---|
| 188 |  | 
|---|
| 189 | #endif /* FT_CONFIG_OPTION_INCREMENTAL */ | 
|---|
| 190 |  | 
|---|
| 191 | return error; | 
|---|
| 192 | } | 
|---|
| 193 |  | 
|---|
| 194 |  | 
|---|
| 195 | /*************************************************************************/ | 
|---|
| 196 | /*************************************************************************/ | 
|---|
| 197 | /*************************************************************************/ | 
|---|
| 198 | /**********                                                      *********/ | 
|---|
| 199 | /**********            COMPUTE THE MAXIMUM ADVANCE WIDTH         *********/ | 
|---|
| 200 | /**********                                                      *********/ | 
|---|
| 201 | /**********    The following code is in charge of computing      *********/ | 
|---|
| 202 | /**********    the maximum advance width of the font.  It        *********/ | 
|---|
| 203 | /**********    quickly processes each glyph charstring to        *********/ | 
|---|
| 204 | /**********    extract the value from either a `sbw' or `seac'   *********/ | 
|---|
| 205 | /**********    operator.                                         *********/ | 
|---|
| 206 | /**********                                                      *********/ | 
|---|
| 207 | /*************************************************************************/ | 
|---|
| 208 | /*************************************************************************/ | 
|---|
| 209 | /*************************************************************************/ | 
|---|
| 210 |  | 
|---|
| 211 |  | 
|---|
| 212 | FT_LOCAL_DEF( FT_Error ) | 
|---|
| 213 | T1_Compute_Max_Advance( T1_Face  face, | 
|---|
| 214 | FT_Pos*  max_advance ) | 
|---|
| 215 | { | 
|---|
| 216 | FT_Error       error; | 
|---|
| 217 | T1_DecoderRec  decoder; | 
|---|
| 218 | FT_Int         glyph_index; | 
|---|
| 219 | T1_Font        type1 = &face->type1; | 
|---|
| 220 | PSAux_Service  psaux = (PSAux_Service)face->psaux; | 
|---|
| 221 |  | 
|---|
| 222 |  | 
|---|
| 223 | FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); | 
|---|
| 224 |  | 
|---|
| 225 | *max_advance = 0; | 
|---|
| 226 |  | 
|---|
| 227 | /* initialize load decoder */ | 
|---|
| 228 | error = psaux->t1_decoder_funcs->init( &decoder, | 
|---|
| 229 | (FT_Face)face, | 
|---|
| 230 | 0, /* size       */ | 
|---|
| 231 | 0, /* glyph slot */ | 
|---|
| 232 | (FT_Byte**)type1->glyph_names, | 
|---|
| 233 | face->blend, | 
|---|
| 234 | 0, | 
|---|
| 235 | FT_RENDER_MODE_NORMAL, | 
|---|
| 236 | T1_Parse_Glyph ); | 
|---|
| 237 | if ( error ) | 
|---|
| 238 | return error; | 
|---|
| 239 |  | 
|---|
| 240 | decoder.builder.metrics_only = 1; | 
|---|
| 241 | decoder.builder.load_points  = 0; | 
|---|
| 242 |  | 
|---|
| 243 | decoder.num_subrs     = type1->num_subrs; | 
|---|
| 244 | decoder.subrs         = type1->subrs; | 
|---|
| 245 | decoder.subrs_len     = type1->subrs_len; | 
|---|
| 246 | decoder.subrs_hash    = type1->subrs_hash; | 
|---|
| 247 |  | 
|---|
| 248 | decoder.buildchar     = face->buildchar; | 
|---|
| 249 | decoder.len_buildchar = face->len_buildchar; | 
|---|
| 250 |  | 
|---|
| 251 | *max_advance = 0; | 
|---|
| 252 |  | 
|---|
| 253 | FT_TRACE6(( "T1_Compute_Max_Advance:\n")); | 
|---|
| 254 |  | 
|---|
| 255 | /* for each glyph, parse the glyph charstring and extract */ | 
|---|
| 256 | /* the advance width                                      */ | 
|---|
| 257 | for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ ) | 
|---|
| 258 | { | 
|---|
| 259 | /* now get load the unscaled outline */ | 
|---|
| 260 | (void)T1_Parse_Glyph( &decoder, (FT_UInt)glyph_index ); | 
|---|
| 261 | if ( glyph_index == 0 || decoder.builder.advance.x > *max_advance ) | 
|---|
| 262 | *max_advance = decoder.builder.advance.x; | 
|---|
| 263 |  | 
|---|
| 264 | /* ignore the error if one occurred - skip to next glyph */ | 
|---|
| 265 | } | 
|---|
| 266 |  | 
|---|
| 267 | FT_TRACE6(( "T1_Compute_Max_Advance: max advance: %f\n", | 
|---|
| 268 | *max_advance / 65536.0 )); | 
|---|
| 269 |  | 
|---|
| 270 | psaux->t1_decoder_funcs->done( &decoder ); | 
|---|
| 271 |  | 
|---|
| 272 | return FT_Err_Ok; | 
|---|
| 273 | } | 
|---|
| 274 |  | 
|---|
| 275 |  | 
|---|
| 276 | FT_LOCAL_DEF( FT_Error ) | 
|---|
| 277 | T1_Get_Advances( FT_Face    t1face,        /* T1_Face */ | 
|---|
| 278 | FT_UInt    first, | 
|---|
| 279 | FT_UInt    count, | 
|---|
| 280 | FT_Int32   load_flags, | 
|---|
| 281 | FT_Fixed*  advances ) | 
|---|
| 282 | { | 
|---|
| 283 | T1_Face        face  = (T1_Face)t1face; | 
|---|
| 284 | T1_DecoderRec  decoder; | 
|---|
| 285 | T1_Font        type1 = &face->type1; | 
|---|
| 286 | PSAux_Service  psaux = (PSAux_Service)face->psaux; | 
|---|
| 287 | FT_UInt        nn; | 
|---|
| 288 | FT_Error       error; | 
|---|
| 289 |  | 
|---|
| 290 |  | 
|---|
| 291 | FT_TRACE5(( "T1_Get_Advances:\n")); | 
|---|
| 292 |  | 
|---|
| 293 | if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) | 
|---|
| 294 | { | 
|---|
| 295 | for ( nn = 0; nn < count; nn++ ) | 
|---|
| 296 | { | 
|---|
| 297 | advances[nn] = 0; | 
|---|
| 298 |  | 
|---|
| 299 | FT_TRACE5(( "  idx %d: advance height 0 font units\n", | 
|---|
| 300 | first + nn )); | 
|---|
| 301 | } | 
|---|
| 302 |  | 
|---|
| 303 | return FT_Err_Ok; | 
|---|
| 304 | } | 
|---|
| 305 |  | 
|---|
| 306 | error = psaux->t1_decoder_funcs->init( &decoder, | 
|---|
| 307 | (FT_Face)face, | 
|---|
| 308 | 0, /* size       */ | 
|---|
| 309 | 0, /* glyph slot */ | 
|---|
| 310 | (FT_Byte**)type1->glyph_names, | 
|---|
| 311 | face->blend, | 
|---|
| 312 | 0, | 
|---|
| 313 | FT_RENDER_MODE_NORMAL, | 
|---|
| 314 | T1_Parse_Glyph ); | 
|---|
| 315 | if ( error ) | 
|---|
| 316 | return error; | 
|---|
| 317 |  | 
|---|
| 318 | decoder.builder.metrics_only = 1; | 
|---|
| 319 | decoder.builder.load_points  = 0; | 
|---|
| 320 |  | 
|---|
| 321 | decoder.num_subrs  = type1->num_subrs; | 
|---|
| 322 | decoder.subrs      = type1->subrs; | 
|---|
| 323 | decoder.subrs_len  = type1->subrs_len; | 
|---|
| 324 | decoder.subrs_hash = type1->subrs_hash; | 
|---|
| 325 |  | 
|---|
| 326 | decoder.buildchar     = face->buildchar; | 
|---|
| 327 | decoder.len_buildchar = face->len_buildchar; | 
|---|
| 328 |  | 
|---|
| 329 | for ( nn = 0; nn < count; nn++ ) | 
|---|
| 330 | { | 
|---|
| 331 | error = T1_Parse_Glyph( &decoder, first + nn ); | 
|---|
| 332 | if ( !error ) | 
|---|
| 333 | advances[nn] = FIXED_TO_INT( decoder.builder.advance.x ); | 
|---|
| 334 | else | 
|---|
| 335 | advances[nn] = 0; | 
|---|
| 336 |  | 
|---|
| 337 | FT_TRACE5(( "  idx %d: advance width %d font unit%s\n", | 
|---|
| 338 | first + nn, | 
|---|
| 339 | advances[nn], | 
|---|
| 340 | advances[nn] == 1 ? "": "s")); | 
|---|
| 341 | } | 
|---|
| 342 |  | 
|---|
| 343 | return FT_Err_Ok; | 
|---|
| 344 | } | 
|---|
| 345 |  | 
|---|
| 346 |  | 
|---|
| 347 | FT_LOCAL_DEF( FT_Error ) | 
|---|
| 348 | T1_Load_Glyph( FT_GlyphSlot  t1glyph,          /* T1_GlyphSlot */ | 
|---|
| 349 | FT_Size       t1size,           /* T1_Size      */ | 
|---|
| 350 | FT_UInt       glyph_index, | 
|---|
| 351 | FT_Int32      load_flags ) | 
|---|
| 352 | { | 
|---|
| 353 | T1_GlyphSlot            glyph = (T1_GlyphSlot)t1glyph; | 
|---|
| 354 | FT_Error                error; | 
|---|
| 355 | T1_DecoderRec           decoder; | 
|---|
| 356 | T1_Face                 face = (T1_Face)t1glyph->face; | 
|---|
| 357 | FT_Bool                 hinting; | 
|---|
| 358 | FT_Bool                 scaled; | 
|---|
| 359 | FT_Bool                 force_scaling = FALSE; | 
|---|
| 360 | T1_Font                 type1         = &face->type1; | 
|---|
| 361 | PSAux_Service           psaux         = (PSAux_Service)face->psaux; | 
|---|
| 362 | const T1_Decoder_Funcs  decoder_funcs = psaux->t1_decoder_funcs; | 
|---|
| 363 |  | 
|---|
| 364 | FT_Matrix               font_matrix; | 
|---|
| 365 | FT_Vector               font_offset; | 
|---|
| 366 | FT_Data                 glyph_data; | 
|---|
| 367 | FT_Bool                 must_finish_decoder = FALSE; | 
|---|
| 368 | #ifdef FT_CONFIG_OPTION_INCREMENTAL | 
|---|
| 369 | FT_Bool                 glyph_data_loaded = 0; | 
|---|
| 370 | #endif | 
|---|
| 371 |  | 
|---|
| 372 |  | 
|---|
| 373 | #ifdef FT_CONFIG_OPTION_INCREMENTAL | 
|---|
| 374 | if ( glyph_index >= (FT_UInt)face->root.num_glyphs && | 
|---|
| 375 | !face->root.internal->incremental_interface   ) | 
|---|
| 376 | #else | 
|---|
| 377 | if ( glyph_index >= (FT_UInt)face->root.num_glyphs ) | 
|---|
| 378 | #endif /* FT_CONFIG_OPTION_INCREMENTAL */ | 
|---|
| 379 | { | 
|---|
| 380 | error = FT_THROW( Invalid_Argument ); | 
|---|
| 381 | goto Exit; | 
|---|
| 382 | } | 
|---|
| 383 |  | 
|---|
| 384 | FT_TRACE1(( "T1_Load_Glyph: glyph index %d\n", glyph_index )); | 
|---|
| 385 |  | 
|---|
| 386 | FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); | 
|---|
| 387 |  | 
|---|
| 388 | if ( load_flags & FT_LOAD_NO_RECURSE ) | 
|---|
| 389 | load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; | 
|---|
| 390 |  | 
|---|
| 391 | if ( t1size ) | 
|---|
| 392 | { | 
|---|
| 393 | glyph->x_scale = t1size->metrics.x_scale; | 
|---|
| 394 | glyph->y_scale = t1size->metrics.y_scale; | 
|---|
| 395 | } | 
|---|
| 396 | else | 
|---|
| 397 | { | 
|---|
| 398 | glyph->x_scale = 0x10000L; | 
|---|
| 399 | glyph->y_scale = 0x10000L; | 
|---|
| 400 | } | 
|---|
| 401 |  | 
|---|
| 402 | t1glyph->outline.n_points   = 0; | 
|---|
| 403 | t1glyph->outline.n_contours = 0; | 
|---|
| 404 |  | 
|---|
| 405 | hinting = FT_BOOL( !( load_flags & FT_LOAD_NO_SCALE   ) && | 
|---|
| 406 | !( load_flags & FT_LOAD_NO_HINTING ) ); | 
|---|
| 407 | scaled  = FT_BOOL( !( load_flags & FT_LOAD_NO_SCALE   ) ); | 
|---|
| 408 |  | 
|---|
| 409 | glyph->hint     = hinting; | 
|---|
| 410 | glyph->scaled   = scaled; | 
|---|
| 411 | t1glyph->format = FT_GLYPH_FORMAT_OUTLINE; | 
|---|
| 412 |  | 
|---|
| 413 | error = decoder_funcs->init( &decoder, | 
|---|
| 414 | t1glyph->face, | 
|---|
| 415 | t1size, | 
|---|
| 416 | t1glyph, | 
|---|
| 417 | (FT_Byte**)type1->glyph_names, | 
|---|
| 418 | face->blend, | 
|---|
| 419 | hinting, | 
|---|
| 420 | FT_LOAD_TARGET_MODE( load_flags ), | 
|---|
| 421 | T1_Parse_Glyph ); | 
|---|
| 422 | if ( error ) | 
|---|
| 423 | goto Exit; | 
|---|
| 424 |  | 
|---|
| 425 | must_finish_decoder = TRUE; | 
|---|
| 426 |  | 
|---|
| 427 | decoder.builder.no_recurse = FT_BOOL( load_flags & FT_LOAD_NO_RECURSE ); | 
|---|
| 428 |  | 
|---|
| 429 | decoder.num_subrs     = type1->num_subrs; | 
|---|
| 430 | decoder.subrs         = type1->subrs; | 
|---|
| 431 | decoder.subrs_len     = type1->subrs_len; | 
|---|
| 432 | decoder.subrs_hash    = type1->subrs_hash; | 
|---|
| 433 |  | 
|---|
| 434 | decoder.buildchar     = face->buildchar; | 
|---|
| 435 | decoder.len_buildchar = face->len_buildchar; | 
|---|
| 436 |  | 
|---|
| 437 | /* now load the unscaled outline */ | 
|---|
| 438 | error = T1_Parse_Glyph_And_Get_Char_String( &decoder, glyph_index, | 
|---|
| 439 | &glyph_data, | 
|---|
| 440 | &force_scaling ); | 
|---|
| 441 | if ( error ) | 
|---|
| 442 | goto Exit; | 
|---|
| 443 | #ifdef FT_CONFIG_OPTION_INCREMENTAL | 
|---|
| 444 | glyph_data_loaded = 1; | 
|---|
| 445 | #endif | 
|---|
| 446 |  | 
|---|
| 447 | hinting     = glyph->hint; | 
|---|
| 448 | font_matrix = decoder.font_matrix; | 
|---|
| 449 | font_offset = decoder.font_offset; | 
|---|
| 450 |  | 
|---|
| 451 | /* save new glyph tables */ | 
|---|
| 452 | decoder_funcs->done( &decoder ); | 
|---|
| 453 |  | 
|---|
| 454 | must_finish_decoder = FALSE; | 
|---|
| 455 |  | 
|---|
| 456 | /* now, set the metrics -- this is rather simple, as   */ | 
|---|
| 457 | /* the left side bearing is the xMin, and the top side */ | 
|---|
| 458 | /* bearing the yMax                                    */ | 
|---|
| 459 | if ( !error ) | 
|---|
| 460 | { | 
|---|
| 461 | t1glyph->outline.flags &= FT_OUTLINE_OWNER; | 
|---|
| 462 | t1glyph->outline.flags |= FT_OUTLINE_REVERSE_FILL; | 
|---|
| 463 |  | 
|---|
| 464 | /* for composite glyphs, return only left side bearing and */ | 
|---|
| 465 | /* advance width                                           */ | 
|---|
| 466 | if ( load_flags & FT_LOAD_NO_RECURSE ) | 
|---|
| 467 | { | 
|---|
| 468 | FT_Slot_Internal  internal = t1glyph->internal; | 
|---|
| 469 |  | 
|---|
| 470 |  | 
|---|
| 471 | t1glyph->metrics.horiBearingX = | 
|---|
| 472 | FIXED_TO_INT( decoder.builder.left_bearing.x ); | 
|---|
| 473 | t1glyph->metrics.horiAdvance  = | 
|---|
| 474 | FIXED_TO_INT( decoder.builder.advance.x ); | 
|---|
| 475 |  | 
|---|
| 476 | internal->glyph_matrix      = font_matrix; | 
|---|
| 477 | internal->glyph_delta       = font_offset; | 
|---|
| 478 | internal->glyph_transformed = 1; | 
|---|
| 479 | } | 
|---|
| 480 | else | 
|---|
| 481 | { | 
|---|
| 482 | FT_BBox            cbox; | 
|---|
| 483 | FT_Glyph_Metrics*  metrics = &t1glyph->metrics; | 
|---|
| 484 |  | 
|---|
| 485 |  | 
|---|
| 486 | /* copy the _unscaled_ advance width */ | 
|---|
| 487 | metrics->horiAdvance = | 
|---|
| 488 | FIXED_TO_INT( decoder.builder.advance.x ); | 
|---|
| 489 | t1glyph->linearHoriAdvance = | 
|---|
| 490 | FIXED_TO_INT( decoder.builder.advance.x ); | 
|---|
| 491 | t1glyph->internal->glyph_transformed = 0; | 
|---|
| 492 |  | 
|---|
| 493 | if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) | 
|---|
| 494 | { | 
|---|
| 495 | /* make up vertical ones */ | 
|---|
| 496 | metrics->vertAdvance = ( face->type1.font_bbox.yMax - | 
|---|
| 497 | face->type1.font_bbox.yMin ) >> 16; | 
|---|
| 498 | t1glyph->linearVertAdvance = metrics->vertAdvance; | 
|---|
| 499 | } | 
|---|
| 500 | else | 
|---|
| 501 | { | 
|---|
| 502 | metrics->vertAdvance = | 
|---|
| 503 | FIXED_TO_INT( decoder.builder.advance.y ); | 
|---|
| 504 | t1glyph->linearVertAdvance = | 
|---|
| 505 | FIXED_TO_INT( decoder.builder.advance.y ); | 
|---|
| 506 | } | 
|---|
| 507 |  | 
|---|
| 508 | t1glyph->format = FT_GLYPH_FORMAT_OUTLINE; | 
|---|
| 509 |  | 
|---|
| 510 | if ( t1size && t1size->metrics.y_ppem < 24 ) | 
|---|
| 511 | t1glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION; | 
|---|
| 512 |  | 
|---|
| 513 | #if 1 | 
|---|
| 514 | /* apply the font matrix, if any */ | 
|---|
| 515 | if ( font_matrix.xx != 0x10000L || font_matrix.yy != 0x10000L || | 
|---|
| 516 | font_matrix.xy != 0        || font_matrix.yx != 0        ) | 
|---|
| 517 | { | 
|---|
| 518 | FT_Outline_Transform( &t1glyph->outline, &font_matrix ); | 
|---|
| 519 |  | 
|---|
| 520 | metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, | 
|---|
| 521 | font_matrix.xx ); | 
|---|
| 522 | metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, | 
|---|
| 523 | font_matrix.yy ); | 
|---|
| 524 | } | 
|---|
| 525 |  | 
|---|
| 526 | if ( font_offset.x || font_offset.y ) | 
|---|
| 527 | { | 
|---|
| 528 | FT_Outline_Translate( &t1glyph->outline, | 
|---|
| 529 | font_offset.x, | 
|---|
| 530 | font_offset.y ); | 
|---|
| 531 |  | 
|---|
| 532 | metrics->horiAdvance += font_offset.x; | 
|---|
| 533 | metrics->vertAdvance += font_offset.y; | 
|---|
| 534 | } | 
|---|
| 535 | #endif | 
|---|
| 536 |  | 
|---|
| 537 | if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 || force_scaling ) | 
|---|
| 538 | { | 
|---|
| 539 | /* scale the outline and the metrics */ | 
|---|
| 540 | FT_Int       n; | 
|---|
| 541 | FT_Outline*  cur = decoder.builder.base; | 
|---|
| 542 | FT_Vector*   vec = cur->points; | 
|---|
| 543 | FT_Fixed     x_scale = glyph->x_scale; | 
|---|
| 544 | FT_Fixed     y_scale = glyph->y_scale; | 
|---|
| 545 |  | 
|---|
| 546 |  | 
|---|
| 547 | /* First of all, scale the points, if we are not hinting */ | 
|---|
| 548 | if ( !hinting || !decoder.builder.hints_funcs ) | 
|---|
| 549 | for ( n = cur->n_points; n > 0; n--, vec++ ) | 
|---|
| 550 | { | 
|---|
| 551 | vec->x = FT_MulFix( vec->x, x_scale ); | 
|---|
| 552 | vec->y = FT_MulFix( vec->y, y_scale ); | 
|---|
| 553 | } | 
|---|
| 554 |  | 
|---|
| 555 | /* Then scale the metrics */ | 
|---|
| 556 | metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); | 
|---|
| 557 | metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); | 
|---|
| 558 | } | 
|---|
| 559 |  | 
|---|
| 560 | /* compute the other metrics */ | 
|---|
| 561 | FT_Outline_Get_CBox( &t1glyph->outline, &cbox ); | 
|---|
| 562 |  | 
|---|
| 563 | metrics->width  = cbox.xMax - cbox.xMin; | 
|---|
| 564 | metrics->height = cbox.yMax - cbox.yMin; | 
|---|
| 565 |  | 
|---|
| 566 | metrics->horiBearingX = cbox.xMin; | 
|---|
| 567 | metrics->horiBearingY = cbox.yMax; | 
|---|
| 568 |  | 
|---|
| 569 | if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) | 
|---|
| 570 | { | 
|---|
| 571 | /* make up vertical ones */ | 
|---|
| 572 | ft_synthesize_vertical_metrics( metrics, | 
|---|
| 573 | metrics->vertAdvance ); | 
|---|
| 574 | } | 
|---|
| 575 | } | 
|---|
| 576 |  | 
|---|
| 577 | /* Set control data to the glyph charstrings.  Note that this is */ | 
|---|
| 578 | /* _not_ zero-terminated.                                        */ | 
|---|
| 579 | t1glyph->control_data = (FT_Byte*)glyph_data.pointer; | 
|---|
| 580 | t1glyph->control_len  = glyph_data.length; | 
|---|
| 581 | } | 
|---|
| 582 |  | 
|---|
| 583 |  | 
|---|
| 584 | Exit: | 
|---|
| 585 |  | 
|---|
| 586 | #ifdef FT_CONFIG_OPTION_INCREMENTAL | 
|---|
| 587 | if ( glyph_data_loaded && face->root.internal->incremental_interface ) | 
|---|
| 588 | { | 
|---|
| 589 | face->root.internal->incremental_interface->funcs->free_glyph_data( | 
|---|
| 590 | face->root.internal->incremental_interface->object, | 
|---|
| 591 | &glyph_data ); | 
|---|
| 592 |  | 
|---|
| 593 | /* Set the control data to null - it is no longer available if   */ | 
|---|
| 594 | /* loaded incrementally.                                         */ | 
|---|
| 595 | t1glyph->control_data = NULL; | 
|---|
| 596 | t1glyph->control_len  = 0; | 
|---|
| 597 | } | 
|---|
| 598 | #endif | 
|---|
| 599 |  | 
|---|
| 600 | if ( must_finish_decoder ) | 
|---|
| 601 | decoder_funcs->done( &decoder ); | 
|---|
| 602 |  | 
|---|
| 603 | return error; | 
|---|
| 604 | } | 
|---|
| 605 |  | 
|---|
| 606 |  | 
|---|
| 607 | /* END */ | 
|---|
| 608 |  | 
|---|