1 /***************************************************************************/
5 /* Type 1 Glyph Loader (body). */
7 /* Copyright 1996-2018 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
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. */
16 /***************************************************************************/
21 #include FT_INTERNAL_CALC_H
22 #include FT_INTERNAL_DEBUG_H
23 #include FT_INTERNAL_STREAM_H
25 #include FT_INTERNAL_POSTSCRIPT_AUX_H
26 #include FT_INTERNAL_CFF_TYPES_H
32 /*************************************************************************/
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. */
39 #define FT_COMPONENT trace_t1gload
43 T1_Parse_Glyph_And_Get_Char_String( T1_Decoder decoder
,
46 FT_Bool
* force_scaling
)
48 T1_Face face
= (T1_Face
)decoder
->builder
.face
;
49 T1_Font type1
= &face
->type1
;
50 FT_Error error
= FT_Err_Ok
;
52 PSAux_Service psaux
= (PSAux_Service
)face
->psaux
;
53 const T1_Decoder_Funcs decoder_funcs
= psaux
->t1_decoder_funcs
;
56 #ifdef FT_CONFIG_OPTION_INCREMENTAL
57 FT_Incremental_InterfaceRec
*inc
=
58 face
->root
.internal
->incremental_interface
;
61 #ifdef T1_CONFIG_OPTION_OLD_ENGINE
62 PS_Driver driver
= (PS_Driver
)FT_FACE_DRIVER( face
);
65 decoder
->font_matrix
= type1
->font_matrix
;
66 decoder
->font_offset
= type1
->font_offset
;
68 #ifdef FT_CONFIG_OPTION_INCREMENTAL
70 /* For incremental fonts get the character data using the */
71 /* callback function. */
73 error
= inc
->funcs
->get_glyph_data( inc
->object
,
74 glyph_index
, char_string
);
77 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
79 /* For ordinary fonts get the character data stored in the face record. */
81 char_string
->pointer
= type1
->charstrings
[glyph_index
];
82 char_string
->length
= (FT_Int
)type1
->charstrings_len
[glyph_index
];
87 /* choose which renderer to use */
88 #ifdef T1_CONFIG_OPTION_OLD_ENGINE
89 if ( driver
->hinting_engine
== FT_HINTING_FREETYPE
||
90 decoder
->builder
.metrics_only
)
91 error
= decoder_funcs
->parse_charstrings_old(
93 (FT_Byte
*)char_string
->pointer
,
94 (FT_UInt
)char_string
->length
);
96 if ( decoder
->builder
.metrics_only
)
97 error
= decoder_funcs
->parse_metrics(
99 (FT_Byte
*)char_string
->pointer
,
100 (FT_UInt
)char_string
->length
);
104 CFF_SubFontRec subfont
;
107 psaux
->ps_decoder_init( &psdecoder
, decoder
, TRUE
);
109 psaux
->t1_make_subfont( FT_FACE( face
),
110 &face
->type1
.private_dict
, &subfont
);
111 psdecoder
.current_subfont
= &subfont
;
113 error
= decoder_funcs
->parse_charstrings(
115 (FT_Byte
*)char_string
->pointer
,
116 (FT_ULong
)char_string
->length
);
118 /* Adobe's engine uses 16.16 numbers everywhere; */
119 /* as a consequence, glyphs larger than 2000ppem get rejected */
120 if ( FT_ERR_EQ( error
, Glyph_Too_Big
) )
122 /* this time, we retry unhinted and scale up the glyph later on */
123 /* (the engine uses and sets the hardcoded value 0x10000 / 64 = */
124 /* 0x400 for both `x_scale' and `y_scale' in this case) */
125 ((T1_GlyphSlot
)decoder
->builder
.glyph
)->hint
= FALSE
;
127 *force_scaling
= TRUE
;
129 error
= decoder_funcs
->parse_charstrings(
131 (FT_Byte
*)char_string
->pointer
,
132 (FT_ULong
)char_string
->length
);
137 #ifdef FT_CONFIG_OPTION_INCREMENTAL
139 /* Incremental fonts can optionally override the metrics. */
140 if ( !error
&& inc
&& inc
->funcs
->get_glyph_metrics
)
142 FT_Incremental_MetricsRec metrics
;
145 metrics
.bearing_x
= FIXED_TO_INT( decoder
->builder
.left_bearing
.x
);
146 metrics
.bearing_y
= 0;
147 metrics
.advance
= FIXED_TO_INT( decoder
->builder
.advance
.x
);
148 metrics
.advance_v
= FIXED_TO_INT( decoder
->builder
.advance
.y
);
150 error
= inc
->funcs
->get_glyph_metrics( inc
->object
,
151 glyph_index
, FALSE
, &metrics
);
153 decoder
->builder
.left_bearing
.x
= INT_TO_FIXED( metrics
.bearing_x
);
154 decoder
->builder
.advance
.x
= INT_TO_FIXED( metrics
.advance
);
155 decoder
->builder
.advance
.y
= INT_TO_FIXED( metrics
.advance_v
);
158 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
164 FT_CALLBACK_DEF( FT_Error
)
165 T1_Parse_Glyph( T1_Decoder decoder
,
166 FT_UInt glyph_index
)
169 FT_Bool force_scaling
= FALSE
;
170 FT_Error error
= T1_Parse_Glyph_And_Get_Char_String(
171 decoder
, glyph_index
, &glyph_data
,
175 #ifdef FT_CONFIG_OPTION_INCREMENTAL
179 T1_Face face
= (T1_Face
)decoder
->builder
.face
;
182 if ( face
->root
.internal
->incremental_interface
)
183 face
->root
.internal
->incremental_interface
->funcs
->free_glyph_data(
184 face
->root
.internal
->incremental_interface
->object
,
188 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
194 /*************************************************************************/
195 /*************************************************************************/
196 /*************************************************************************/
197 /********** *********/
198 /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/
199 /********** *********/
200 /********** The following code is in charge of computing *********/
201 /********** the maximum advance width of the font. It *********/
202 /********** quickly processes each glyph charstring to *********/
203 /********** extract the value from either a `sbw' or `seac' *********/
204 /********** operator. *********/
205 /********** *********/
206 /*************************************************************************/
207 /*************************************************************************/
208 /*************************************************************************/
211 FT_LOCAL_DEF( FT_Error
)
212 T1_Compute_Max_Advance( T1_Face face
,
213 FT_Pos
* max_advance
)
217 T1_DecoderRec
*decoder
= malloc(sizeof(T1_DecoderRec
));
218 /* Ugly but it allows us to reduce the diff */
219 #define decoder (*decoder)
221 T1_DecoderRec decoder
;
224 T1_Font type1
= &face
->type1
;
225 PSAux_Service psaux
= (PSAux_Service
)face
->psaux
;
228 FT_ASSERT( ( face
->len_buildchar
== 0 ) == ( face
->buildchar
== NULL
) );
232 /* initialize load decoder */
233 error
= psaux
->t1_decoder_funcs
->init( &decoder
,
237 (FT_Byte
**)type1
->glyph_names
,
240 FT_RENDER_MODE_NORMAL
,
252 decoder
.builder
.metrics_only
= 1;
253 decoder
.builder
.load_points
= 0;
255 decoder
.num_subrs
= type1
->num_subrs
;
256 decoder
.subrs
= type1
->subrs
;
257 decoder
.subrs_len
= type1
->subrs_len
;
258 decoder
.subrs_hash
= type1
->subrs_hash
;
260 decoder
.buildchar
= face
->buildchar
;
261 decoder
.len_buildchar
= face
->len_buildchar
;
265 /* for each glyph, parse the glyph charstring and extract */
266 /* the advance width */
267 for ( glyph_index
= 0; glyph_index
< type1
->num_glyphs
; glyph_index
++ )
269 /* now get load the unscaled outline */
270 (void)T1_Parse_Glyph( &decoder
, (FT_UInt
)glyph_index
);
271 if ( glyph_index
== 0 || decoder
.builder
.advance
.x
> *max_advance
)
272 *max_advance
= decoder
.builder
.advance
.x
;
274 /* ignore the error if one occurred - skip to next glyph */
277 psaux
->t1_decoder_funcs
->done( &decoder
);
287 FT_LOCAL_DEF( FT_Error
)
288 T1_Get_Advances( FT_Face t1face
, /* T1_Face */
294 T1_Face face
= (T1_Face
)t1face
;
296 T1_DecoderRec
*decoder
= malloc(sizeof(T1_DecoderRec
));
297 /* Ugly but it allows us to reduce the diff */
298 #define decoder (*decoder)
300 T1_DecoderRec decoder
;
302 T1_Font type1
= &face
->type1
;
303 PSAux_Service psaux
= (PSAux_Service
)face
->psaux
;
308 if ( load_flags
& FT_LOAD_VERTICAL_LAYOUT
)
310 for ( nn
= 0; nn
< count
; nn
++ )
319 error
= psaux
->t1_decoder_funcs
->init( &decoder
,
323 (FT_Byte
**)type1
->glyph_names
,
326 FT_RENDER_MODE_NORMAL
,
338 decoder
.builder
.metrics_only
= 1;
339 decoder
.builder
.load_points
= 0;
341 decoder
.num_subrs
= type1
->num_subrs
;
342 decoder
.subrs
= type1
->subrs
;
343 decoder
.subrs_len
= type1
->subrs_len
;
344 decoder
.subrs_hash
= type1
->subrs_hash
;
346 decoder
.buildchar
= face
->buildchar
;
347 decoder
.len_buildchar
= face
->len_buildchar
;
349 for ( nn
= 0; nn
< count
; nn
++ )
351 error
= T1_Parse_Glyph( &decoder
, first
+ nn
);
353 advances
[nn
] = FIXED_TO_INT( decoder
.builder
.advance
.x
);
366 FT_LOCAL_DEF( FT_Error
)
367 T1_Load_Glyph( FT_GlyphSlot t1glyph
, /* T1_GlyphSlot */
368 FT_Size t1size
, /* T1_Size */
370 FT_Int32 load_flags
)
372 T1_GlyphSlot glyph
= (T1_GlyphSlot
)t1glyph
;
375 T1_DecoderRec
*decoder
= malloc(sizeof(T1_DecoderRec
));
376 /* Ugly but it allows us to reduce the diff */
377 #define decoder (*decoder)
379 T1_DecoderRec decoder
;
381 T1_Face face
= (T1_Face
)t1glyph
->face
;
384 FT_Bool force_scaling
= FALSE
;
385 T1_Font type1
= &face
->type1
;
386 PSAux_Service psaux
= (PSAux_Service
)face
->psaux
;
387 const T1_Decoder_Funcs decoder_funcs
= psaux
->t1_decoder_funcs
;
389 FT_Matrix font_matrix
;
390 FT_Vector font_offset
;
392 FT_Bool must_finish_decoder
= FALSE
;
393 #ifdef FT_CONFIG_OPTION_INCREMENTAL
394 FT_Bool glyph_data_loaded
= 0;
398 #ifdef FT_CONFIG_OPTION_INCREMENTAL
399 if ( glyph_index
>= (FT_UInt
)face
->root
.num_glyphs
&&
400 !face
->root
.internal
->incremental_interface
)
402 if ( glyph_index
>= (FT_UInt
)face
->root
.num_glyphs
)
403 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
405 error
= FT_THROW( Invalid_Argument
);
409 FT_TRACE1(( "T1_Load_Glyph: glyph index %d\n", glyph_index
));
411 FT_ASSERT( ( face
->len_buildchar
== 0 ) == ( face
->buildchar
== NULL
) );
413 if ( load_flags
& FT_LOAD_NO_RECURSE
)
414 load_flags
|= FT_LOAD_NO_SCALE
| FT_LOAD_NO_HINTING
;
418 glyph
->x_scale
= t1size
->metrics
.x_scale
;
419 glyph
->y_scale
= t1size
->metrics
.y_scale
;
423 glyph
->x_scale
= 0x10000L
;
424 glyph
->y_scale
= 0x10000L
;
427 t1glyph
->outline
.n_points
= 0;
428 t1glyph
->outline
.n_contours
= 0;
430 hinting
= FT_BOOL( ( load_flags
& FT_LOAD_NO_SCALE
) == 0 &&
431 ( load_flags
& FT_LOAD_NO_HINTING
) == 0 );
432 scaled
= FT_BOOL( ( load_flags
& FT_LOAD_NO_SCALE
) == 0 );
434 glyph
->hint
= hinting
;
435 glyph
->scaled
= scaled
;
436 t1glyph
->format
= FT_GLYPH_FORMAT_OUTLINE
;
438 error
= decoder_funcs
->init( &decoder
,
442 (FT_Byte
**)type1
->glyph_names
,
445 FT_LOAD_TARGET_MODE( load_flags
),
450 must_finish_decoder
= TRUE
;
452 decoder
.builder
.no_recurse
= FT_BOOL(
453 ( load_flags
& FT_LOAD_NO_RECURSE
) != 0 );
455 decoder
.num_subrs
= type1
->num_subrs
;
456 decoder
.subrs
= type1
->subrs
;
457 decoder
.subrs_len
= type1
->subrs_len
;
458 decoder
.subrs_hash
= type1
->subrs_hash
;
460 decoder
.buildchar
= face
->buildchar
;
461 decoder
.len_buildchar
= face
->len_buildchar
;
463 /* now load the unscaled outline */
464 error
= T1_Parse_Glyph_And_Get_Char_String( &decoder
, glyph_index
,
469 #ifdef FT_CONFIG_OPTION_INCREMENTAL
470 glyph_data_loaded
= 1;
473 hinting
= glyph
->hint
;
474 font_matrix
= decoder
.font_matrix
;
475 font_offset
= decoder
.font_offset
;
477 /* save new glyph tables */
478 decoder_funcs
->done( &decoder
);
480 must_finish_decoder
= FALSE
;
482 /* now, set the metrics -- this is rather simple, as */
483 /* the left side bearing is the xMin, and the top side */
484 /* bearing the yMax */
487 t1glyph
->outline
.flags
&= FT_OUTLINE_OWNER
;
488 t1glyph
->outline
.flags
|= FT_OUTLINE_REVERSE_FILL
;
490 /* for composite glyphs, return only left side bearing and */
492 if ( load_flags
& FT_LOAD_NO_RECURSE
)
494 FT_Slot_Internal internal
= t1glyph
->internal
;
497 t1glyph
->metrics
.horiBearingX
=
498 FIXED_TO_INT( decoder
.builder
.left_bearing
.x
);
499 t1glyph
->metrics
.horiAdvance
=
500 FIXED_TO_INT( decoder
.builder
.advance
.x
);
502 internal
->glyph_matrix
= font_matrix
;
503 internal
->glyph_delta
= font_offset
;
504 internal
->glyph_transformed
= 1;
509 FT_Glyph_Metrics
* metrics
= &t1glyph
->metrics
;
512 /* copy the _unscaled_ advance width */
513 metrics
->horiAdvance
=
514 FIXED_TO_INT( decoder
.builder
.advance
.x
);
515 t1glyph
->linearHoriAdvance
=
516 FIXED_TO_INT( decoder
.builder
.advance
.x
);
517 t1glyph
->internal
->glyph_transformed
= 0;
519 if ( load_flags
& FT_LOAD_VERTICAL_LAYOUT
)
521 /* make up vertical ones */
522 metrics
->vertAdvance
= ( face
->type1
.font_bbox
.yMax
-
523 face
->type1
.font_bbox
.yMin
) >> 16;
524 t1glyph
->linearVertAdvance
= metrics
->vertAdvance
;
528 metrics
->vertAdvance
=
529 FIXED_TO_INT( decoder
.builder
.advance
.y
);
530 t1glyph
->linearVertAdvance
=
531 FIXED_TO_INT( decoder
.builder
.advance
.y
);
534 t1glyph
->format
= FT_GLYPH_FORMAT_OUTLINE
;
536 if ( t1size
&& t1size
->metrics
.y_ppem
< 24 )
537 t1glyph
->outline
.flags
|= FT_OUTLINE_HIGH_PRECISION
;
540 /* apply the font matrix, if any */
541 if ( font_matrix
.xx
!= 0x10000L
|| font_matrix
.yy
!= 0x10000L
||
542 font_matrix
.xy
!= 0 || font_matrix
.yx
!= 0 )
544 FT_Outline_Transform( &t1glyph
->outline
, &font_matrix
);
546 metrics
->horiAdvance
= FT_MulFix( metrics
->horiAdvance
,
548 metrics
->vertAdvance
= FT_MulFix( metrics
->vertAdvance
,
552 if ( font_offset
.x
|| font_offset
.y
)
554 FT_Outline_Translate( &t1glyph
->outline
,
558 metrics
->horiAdvance
+= font_offset
.x
;
559 metrics
->vertAdvance
+= font_offset
.y
;
563 if ( ( load_flags
& FT_LOAD_NO_SCALE
) == 0 || force_scaling
)
565 /* scale the outline and the metrics */
567 FT_Outline
* cur
= decoder
.builder
.base
;
568 FT_Vector
* vec
= cur
->points
;
569 FT_Fixed x_scale
= glyph
->x_scale
;
570 FT_Fixed y_scale
= glyph
->y_scale
;
573 /* First of all, scale the points, if we are not hinting */
574 if ( !hinting
|| ! decoder
.builder
.hints_funcs
)
575 for ( n
= cur
->n_points
; n
> 0; n
--, vec
++ )
577 vec
->x
= FT_MulFix( vec
->x
, x_scale
);
578 vec
->y
= FT_MulFix( vec
->y
, y_scale
);
581 /* Then scale the metrics */
582 metrics
->horiAdvance
= FT_MulFix( metrics
->horiAdvance
, x_scale
);
583 metrics
->vertAdvance
= FT_MulFix( metrics
->vertAdvance
, y_scale
);
586 /* compute the other metrics */
587 FT_Outline_Get_CBox( &t1glyph
->outline
, &cbox
);
589 metrics
->width
= cbox
.xMax
- cbox
.xMin
;
590 metrics
->height
= cbox
.yMax
- cbox
.yMin
;
592 metrics
->horiBearingX
= cbox
.xMin
;
593 metrics
->horiBearingY
= cbox
.yMax
;
595 if ( load_flags
& FT_LOAD_VERTICAL_LAYOUT
)
597 /* make up vertical ones */
598 ft_synthesize_vertical_metrics( metrics
,
599 metrics
->vertAdvance
);
603 /* Set control data to the glyph charstrings. Note that this is */
604 /* _not_ zero-terminated. */
605 t1glyph
->control_data
= (FT_Byte
*)glyph_data
.pointer
;
606 t1glyph
->control_len
= glyph_data
.length
;
612 #ifdef FT_CONFIG_OPTION_INCREMENTAL
613 if ( glyph_data_loaded
&& face
->root
.internal
->incremental_interface
)
615 face
->root
.internal
->incremental_interface
->funcs
->free_glyph_data(
616 face
->root
.internal
->incremental_interface
->object
,
619 /* Set the control data to null - it is no longer available if */
620 /* loaded incrementally. */
621 t1glyph
->control_data
= NULL
;
622 t1glyph
->control_len
= 0;
626 if ( must_finish_decoder
)
627 decoder_funcs
->done( &decoder
);