1 /***************************************************************************/
2 /* */
3 /* t1gload.c */
4 /* */
5 /* Type 1 Glyph Loader (body). */
6 /* */
7 /* Copyright 1996-2018 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 trace_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 decoder->font_matrix = type1->font_matrix;
66 decoder->font_offset = type1->font_offset;
67
68 #ifdef FT_CONFIG_OPTION_INCREMENTAL
69
70 /* For incremental fonts get the character data using the */
71 /* callback function. */
72 if ( inc )
73 error = inc->funcs->get_glyph_data( inc->object,
74 glyph_index, char_string );
75 else
76
77 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
78
79 /* For ordinary fonts get the character data stored in the face record. */
80 {
81 char_string->pointer = type1->charstrings[glyph_index];
82 char_string->length = (FT_Int)type1->charstrings_len[glyph_index];
83 }
84
232 face->blend,
233 0,
234 FT_RENDER_MODE_NORMAL,
235 T1_Parse_Glyph );
236 if ( error )
237 return error;
238
239 decoder.builder.metrics_only = 1;
240 decoder.builder.load_points = 0;
241
242 decoder.num_subrs = type1->num_subrs;
243 decoder.subrs = type1->subrs;
244 decoder.subrs_len = type1->subrs_len;
245 decoder.subrs_hash = type1->subrs_hash;
246
247 decoder.buildchar = face->buildchar;
248 decoder.len_buildchar = face->len_buildchar;
249
250 *max_advance = 0;
251
252 /* for each glyph, parse the glyph charstring and extract */
253 /* the advance width */
254 for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ )
255 {
256 /* now get load the unscaled outline */
257 (void)T1_Parse_Glyph( &decoder, (FT_UInt)glyph_index );
258 if ( glyph_index == 0 || decoder.builder.advance.x > *max_advance )
259 *max_advance = decoder.builder.advance.x;
260
261 /* ignore the error if one occurred - skip to next glyph */
262 }
263
264 psaux->t1_decoder_funcs->done( &decoder );
265
266 return FT_Err_Ok;
267 }
268
269
270 FT_LOCAL_DEF( FT_Error )
271 T1_Get_Advances( FT_Face t1face, /* T1_Face */
272 FT_UInt first,
273 FT_UInt count,
274 FT_Int32 load_flags,
275 FT_Fixed* advances )
276 {
277 T1_Face face = (T1_Face)t1face;
278 T1_DecoderRec decoder;
279 T1_Font type1 = &face->type1;
280 PSAux_Service psaux = (PSAux_Service)face->psaux;
281 FT_UInt nn;
282 FT_Error error;
283
284
285 if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
286 {
287 for ( nn = 0; nn < count; nn++ )
288 advances[nn] = 0;
289
290 return FT_Err_Ok;
291 }
292
293 error = psaux->t1_decoder_funcs->init( &decoder,
294 (FT_Face)face,
295 0, /* size */
296 0, /* glyph slot */
297 (FT_Byte**)type1->glyph_names,
298 face->blend,
299 0,
300 FT_RENDER_MODE_NORMAL,
301 T1_Parse_Glyph );
302 if ( error )
303 return error;
304
305 decoder.builder.metrics_only = 1;
306 decoder.builder.load_points = 0;
307
308 decoder.num_subrs = type1->num_subrs;
309 decoder.subrs = type1->subrs;
310 decoder.subrs_len = type1->subrs_len;
311 decoder.subrs_hash = type1->subrs_hash;
312
313 decoder.buildchar = face->buildchar;
314 decoder.len_buildchar = face->len_buildchar;
315
316 for ( nn = 0; nn < count; nn++ )
317 {
318 error = T1_Parse_Glyph( &decoder, first + nn );
319 if ( !error )
320 advances[nn] = FIXED_TO_INT( decoder.builder.advance.x );
321 else
322 advances[nn] = 0;
323 }
324
325 return FT_Err_Ok;
326 }
327
328
329 FT_LOCAL_DEF( FT_Error )
330 T1_Load_Glyph( FT_GlyphSlot t1glyph, /* T1_GlyphSlot */
331 FT_Size t1size, /* T1_Size */
332 FT_UInt glyph_index,
333 FT_Int32 load_flags )
334 {
335 T1_GlyphSlot glyph = (T1_GlyphSlot)t1glyph;
336 FT_Error error;
337 T1_DecoderRec decoder;
338 T1_Face face = (T1_Face)t1glyph->face;
339 FT_Bool hinting;
340 FT_Bool scaled;
341 FT_Bool force_scaling = FALSE;
342 T1_Font type1 = &face->type1;
367
368 FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) );
369
370 if ( load_flags & FT_LOAD_NO_RECURSE )
371 load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
372
373 if ( t1size )
374 {
375 glyph->x_scale = t1size->metrics.x_scale;
376 glyph->y_scale = t1size->metrics.y_scale;
377 }
378 else
379 {
380 glyph->x_scale = 0x10000L;
381 glyph->y_scale = 0x10000L;
382 }
383
384 t1glyph->outline.n_points = 0;
385 t1glyph->outline.n_contours = 0;
386
387 hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 &&
388 ( load_flags & FT_LOAD_NO_HINTING ) == 0 );
389 scaled = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 );
390
391 glyph->hint = hinting;
392 glyph->scaled = scaled;
393 t1glyph->format = FT_GLYPH_FORMAT_OUTLINE;
394
395 error = decoder_funcs->init( &decoder,
396 t1glyph->face,
397 t1size,
398 t1glyph,
399 (FT_Byte**)type1->glyph_names,
400 face->blend,
401 FT_BOOL( hinting ),
402 FT_LOAD_TARGET_MODE( load_flags ),
403 T1_Parse_Glyph );
404 if ( error )
405 goto Exit;
406
407 must_finish_decoder = TRUE;
408
409 decoder.builder.no_recurse = FT_BOOL(
410 ( load_flags & FT_LOAD_NO_RECURSE ) != 0 );
411
412 decoder.num_subrs = type1->num_subrs;
413 decoder.subrs = type1->subrs;
414 decoder.subrs_len = type1->subrs_len;
415 decoder.subrs_hash = type1->subrs_hash;
416
417 decoder.buildchar = face->buildchar;
418 decoder.len_buildchar = face->len_buildchar;
419
420 /* now load the unscaled outline */
421 error = T1_Parse_Glyph_And_Get_Char_String( &decoder, glyph_index,
422 &glyph_data,
423 &force_scaling );
424 if ( error )
425 goto Exit;
426 #ifdef FT_CONFIG_OPTION_INCREMENTAL
427 glyph_data_loaded = 1;
428 #endif
429
430 hinting = glyph->hint;
511 FT_Outline_Translate( &t1glyph->outline,
512 font_offset.x,
513 font_offset.y );
514
515 metrics->horiAdvance += font_offset.x;
516 metrics->vertAdvance += font_offset.y;
517 }
518 #endif
519
520 if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 || force_scaling )
521 {
522 /* scale the outline and the metrics */
523 FT_Int n;
524 FT_Outline* cur = decoder.builder.base;
525 FT_Vector* vec = cur->points;
526 FT_Fixed x_scale = glyph->x_scale;
527 FT_Fixed y_scale = glyph->y_scale;
528
529
530 /* First of all, scale the points, if we are not hinting */
531 if ( !hinting || ! decoder.builder.hints_funcs )
532 for ( n = cur->n_points; n > 0; n--, vec++ )
533 {
534 vec->x = FT_MulFix( vec->x, x_scale );
535 vec->y = FT_MulFix( vec->y, y_scale );
536 }
537
538 /* Then scale the metrics */
539 metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
540 metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );
541 }
542
543 /* compute the other metrics */
544 FT_Outline_Get_CBox( &t1glyph->outline, &cbox );
545
546 metrics->width = cbox.xMax - cbox.xMin;
547 metrics->height = cbox.yMax - cbox.yMin;
548
549 metrics->horiBearingX = cbox.xMin;
550 metrics->horiBearingY = cbox.yMax;
551
|
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
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;
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;
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
|