1 /***************************************************************************/
5 /* Type 1 Glyph Loader (body). */
7 /* Copyright 1996-2006, 2008-2010, 2013 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
30 /*************************************************************************/
32 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
33 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
34 /* messages during execution. */
37 #define FT_COMPONENT trace_t1gload
40 /*************************************************************************/
41 /*************************************************************************/
42 /*************************************************************************/
43 /********** *********/
44 /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/
45 /********** *********/
46 /********** The following code is in charge of computing *********/
47 /********** the maximum advance width of the font. It *********/
48 /********** quickly processes each glyph charstring to *********/
49 /********** extract the value from either a `sbw' or `seac' *********/
50 /********** operator. *********/
51 /********** *********/
52 /*************************************************************************/
53 /*************************************************************************/
54 /*************************************************************************/
57 FT_LOCAL_DEF( FT_Error
)
58 T1_Parse_Glyph_And_Get_Char_String( T1_Decoder decoder
,
60 FT_Data
* char_string
)
62 T1_Face face
= (T1_Face
)decoder
->builder
.face
;
63 T1_Font type1
= &face
->type1
;
64 FT_Error error
= FT_Err_Ok
;
66 #ifdef FT_CONFIG_OPTION_INCREMENTAL
67 FT_Incremental_InterfaceRec
*inc
=
68 face
->root
.internal
->incremental_interface
;
72 decoder
->font_matrix
= type1
->font_matrix
;
73 decoder
->font_offset
= type1
->font_offset
;
75 #ifdef FT_CONFIG_OPTION_INCREMENTAL
77 /* For incremental fonts get the character data using the */
78 /* callback function. */
80 error
= inc
->funcs
->get_glyph_data( inc
->object
,
81 glyph_index
, char_string
);
84 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
86 /* For ordinary fonts get the character data stored in the face record. */
88 char_string
->pointer
= type1
->charstrings
[glyph_index
];
89 char_string
->length
= (FT_Int
)type1
->charstrings_len
[glyph_index
];
93 error
= decoder
->funcs
.parse_charstrings(
94 decoder
, (FT_Byte
*)char_string
->pointer
,
95 char_string
->length
);
97 #ifdef FT_CONFIG_OPTION_INCREMENTAL
99 /* Incremental fonts can optionally override the metrics. */
100 if ( !error
&& inc
&& inc
->funcs
->get_glyph_metrics
)
102 FT_Incremental_MetricsRec metrics
;
105 metrics
.bearing_x
= FIXED_TO_INT( decoder
->builder
.left_bearing
.x
);
106 metrics
.bearing_y
= 0;
107 metrics
.advance
= FIXED_TO_INT( decoder
->builder
.advance
.x
);
108 metrics
.advance_v
= FIXED_TO_INT( decoder
->builder
.advance
.y
);
110 error
= inc
->funcs
->get_glyph_metrics( inc
->object
,
111 glyph_index
, FALSE
, &metrics
);
113 decoder
->builder
.left_bearing
.x
= INT_TO_FIXED( metrics
.bearing_x
);
114 decoder
->builder
.advance
.x
= INT_TO_FIXED( metrics
.advance
);
115 decoder
->builder
.advance
.y
= INT_TO_FIXED( metrics
.advance_v
);
118 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
124 FT_CALLBACK_DEF( FT_Error
)
125 T1_Parse_Glyph( T1_Decoder decoder
,
126 FT_UInt glyph_index
)
129 FT_Error error
= T1_Parse_Glyph_And_Get_Char_String(
130 decoder
, glyph_index
, &glyph_data
);
133 #ifdef FT_CONFIG_OPTION_INCREMENTAL
137 T1_Face face
= (T1_Face
)decoder
->builder
.face
;
140 if ( face
->root
.internal
->incremental_interface
)
141 face
->root
.internal
->incremental_interface
->funcs
->free_glyph_data(
142 face
->root
.internal
->incremental_interface
->object
,
146 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
152 FT_LOCAL_DEF( FT_Error
)
153 T1_Compute_Max_Advance( T1_Face face
,
154 FT_Pos
* max_advance
)
157 T1_DecoderRec decoder
;
159 T1_Font type1
= &face
->type1
;
160 PSAux_Service psaux
= (PSAux_Service
)face
->psaux
;
163 FT_ASSERT( ( face
->len_buildchar
== 0 ) == ( face
->buildchar
== NULL
) );
167 /* initialize load decoder */
168 error
= psaux
->t1_decoder_funcs
->init( &decoder
,
172 (FT_Byte
**)type1
->glyph_names
,
175 FT_RENDER_MODE_NORMAL
,
180 decoder
.builder
.metrics_only
= 1;
181 decoder
.builder
.load_points
= 0;
183 decoder
.num_subrs
= type1
->num_subrs
;
184 decoder
.subrs
= type1
->subrs
;
185 decoder
.subrs_len
= type1
->subrs_len
;
187 decoder
.buildchar
= face
->buildchar
;
188 decoder
.len_buildchar
= face
->len_buildchar
;
192 /* for each glyph, parse the glyph charstring and extract */
193 /* the advance width */
194 for ( glyph_index
= 0; glyph_index
< type1
->num_glyphs
; glyph_index
++ )
196 /* now get load the unscaled outline */
197 error
= T1_Parse_Glyph( &decoder
, glyph_index
);
198 if ( glyph_index
== 0 || decoder
.builder
.advance
.x
> *max_advance
)
199 *max_advance
= decoder
.builder
.advance
.x
;
201 /* ignore the error if one occurred - skip to next glyph */
204 psaux
->t1_decoder_funcs
->done( &decoder
);
210 FT_LOCAL_DEF( FT_Error
)
211 T1_Get_Advances( FT_Face t1face
, /* T1_Face */
217 T1_Face face
= (T1_Face
)t1face
;
218 T1_DecoderRec decoder
;
219 T1_Font type1
= &face
->type1
;
220 PSAux_Service psaux
= (PSAux_Service
)face
->psaux
;
225 if ( load_flags
& FT_LOAD_VERTICAL_LAYOUT
)
227 for ( nn
= 0; nn
< count
; nn
++ )
233 error
= psaux
->t1_decoder_funcs
->init( &decoder
,
237 (FT_Byte
**)type1
->glyph_names
,
240 FT_RENDER_MODE_NORMAL
,
245 decoder
.builder
.metrics_only
= 1;
246 decoder
.builder
.load_points
= 0;
248 decoder
.num_subrs
= type1
->num_subrs
;
249 decoder
.subrs
= type1
->subrs
;
250 decoder
.subrs_len
= type1
->subrs_len
;
252 decoder
.buildchar
= face
->buildchar
;
253 decoder
.len_buildchar
= face
->len_buildchar
;
255 for ( nn
= 0; nn
< count
; nn
++ )
257 error
= T1_Parse_Glyph( &decoder
, first
+ nn
);
259 advances
[nn
] = FIXED_TO_INT( decoder
.builder
.advance
.x
);
268 FT_LOCAL_DEF( FT_Error
)
269 T1_Load_Glyph( FT_GlyphSlot t1glyph
, /* T1_GlyphSlot */
270 FT_Size t1size
, /* T1_Size */
272 FT_Int32 load_flags
)
274 T1_GlyphSlot glyph
= (T1_GlyphSlot
)t1glyph
;
276 T1_DecoderRec decoder
;
277 T1_Face face
= (T1_Face
)t1glyph
->face
;
279 T1_Font type1
= &face
->type1
;
280 PSAux_Service psaux
= (PSAux_Service
)face
->psaux
;
281 const T1_Decoder_Funcs decoder_funcs
= psaux
->t1_decoder_funcs
;
283 FT_Matrix font_matrix
;
284 FT_Vector font_offset
;
286 FT_Bool must_finish_decoder
= FALSE
;
287 #ifdef FT_CONFIG_OPTION_INCREMENTAL
288 FT_Bool glyph_data_loaded
= 0;
292 #ifdef FT_CONFIG_OPTION_INCREMENTAL
293 if ( glyph_index
>= (FT_UInt
)face
->root
.num_glyphs
&&
294 !face
->root
.internal
->incremental_interface
)
296 if ( glyph_index
>= (FT_UInt
)face
->root
.num_glyphs
)
297 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
299 error
= FT_THROW( Invalid_Argument
);
303 FT_TRACE1(( "T1_Load_Glyph: glyph index %d\n", glyph_index
));
305 FT_ASSERT( ( face
->len_buildchar
== 0 ) == ( face
->buildchar
== NULL
) );
307 if ( load_flags
& FT_LOAD_NO_RECURSE
)
308 load_flags
|= FT_LOAD_NO_SCALE
| FT_LOAD_NO_HINTING
;
312 glyph
->x_scale
= t1size
->metrics
.x_scale
;
313 glyph
->y_scale
= t1size
->metrics
.y_scale
;
317 glyph
->x_scale
= 0x10000L
;
318 glyph
->y_scale
= 0x10000L
;
321 t1glyph
->outline
.n_points
= 0;
322 t1glyph
->outline
.n_contours
= 0;
324 hinting
= FT_BOOL( ( load_flags
& FT_LOAD_NO_SCALE
) == 0 &&
325 ( load_flags
& FT_LOAD_NO_HINTING
) == 0 );
327 t1glyph
->format
= FT_GLYPH_FORMAT_OUTLINE
;
329 error
= decoder_funcs
->init( &decoder
,
333 (FT_Byte
**)type1
->glyph_names
,
336 FT_LOAD_TARGET_MODE( load_flags
),
341 must_finish_decoder
= TRUE
;
343 decoder
.builder
.no_recurse
= FT_BOOL(
344 ( load_flags
& FT_LOAD_NO_RECURSE
) != 0 );
346 decoder
.num_subrs
= type1
->num_subrs
;
347 decoder
.subrs
= type1
->subrs
;
348 decoder
.subrs_len
= type1
->subrs_len
;
350 decoder
.buildchar
= face
->buildchar
;
351 decoder
.len_buildchar
= face
->len_buildchar
;
353 /* now load the unscaled outline */
354 error
= T1_Parse_Glyph_And_Get_Char_String( &decoder
, glyph_index
,
358 #ifdef FT_CONFIG_OPTION_INCREMENTAL
359 glyph_data_loaded
= 1;
362 font_matrix
= decoder
.font_matrix
;
363 font_offset
= decoder
.font_offset
;
365 /* save new glyph tables */
366 decoder_funcs
->done( &decoder
);
368 must_finish_decoder
= FALSE
;
370 /* now, set the metrics -- this is rather simple, as */
371 /* the left side bearing is the xMin, and the top side */
372 /* bearing the yMax */
375 t1glyph
->outline
.flags
&= FT_OUTLINE_OWNER
;
376 t1glyph
->outline
.flags
|= FT_OUTLINE_REVERSE_FILL
;
378 /* for composite glyphs, return only left side bearing and */
380 if ( load_flags
& FT_LOAD_NO_RECURSE
)
382 FT_Slot_Internal internal
= t1glyph
->internal
;
385 t1glyph
->metrics
.horiBearingX
=
386 FIXED_TO_INT( decoder
.builder
.left_bearing
.x
);
387 t1glyph
->metrics
.horiAdvance
=
388 FIXED_TO_INT( decoder
.builder
.advance
.x
);
390 internal
->glyph_matrix
= font_matrix
;
391 internal
->glyph_delta
= font_offset
;
392 internal
->glyph_transformed
= 1;
397 FT_Glyph_Metrics
* metrics
= &t1glyph
->metrics
;
401 /* copy the _unscaled_ advance width */
402 metrics
->horiAdvance
=
403 FIXED_TO_INT( decoder
.builder
.advance
.x
);
404 t1glyph
->linearHoriAdvance
=
405 FIXED_TO_INT( decoder
.builder
.advance
.x
);
406 t1glyph
->internal
->glyph_transformed
= 0;
408 if ( load_flags
& FT_LOAD_VERTICAL_LAYOUT
)
410 /* make up vertical ones */
411 metrics
->vertAdvance
= ( face
->type1
.font_bbox
.yMax
-
412 face
->type1
.font_bbox
.yMin
) >> 16;
413 t1glyph
->linearVertAdvance
= metrics
->vertAdvance
;
417 metrics
->vertAdvance
=
418 FIXED_TO_INT( decoder
.builder
.advance
.y
);
419 t1glyph
->linearVertAdvance
=
420 FIXED_TO_INT( decoder
.builder
.advance
.y
);
423 t1glyph
->format
= FT_GLYPH_FORMAT_OUTLINE
;
425 if ( t1size
&& t1size
->metrics
.y_ppem
< 24 )
426 t1glyph
->outline
.flags
|= FT_OUTLINE_HIGH_PRECISION
;
429 /* apply the font matrix, if any */
430 if ( font_matrix
.xx
!= 0x10000L
|| font_matrix
.yy
!= font_matrix
.xx
||
431 font_matrix
.xy
!= 0 || font_matrix
.yx
!= 0 )
432 FT_Outline_Transform( &t1glyph
->outline
, &font_matrix
);
434 if ( font_offset
.x
|| font_offset
.y
)
435 FT_Outline_Translate( &t1glyph
->outline
,
439 advance
.x
= metrics
->horiAdvance
;
441 FT_Vector_Transform( &advance
, &font_matrix
);
442 metrics
->horiAdvance
= advance
.x
+ font_offset
.x
;
444 advance
.y
= metrics
->vertAdvance
;
445 FT_Vector_Transform( &advance
, &font_matrix
);
446 metrics
->vertAdvance
= advance
.y
+ font_offset
.y
;
449 if ( ( load_flags
& FT_LOAD_NO_SCALE
) == 0 )
451 /* scale the outline and the metrics */
453 FT_Outline
* cur
= decoder
.builder
.base
;
454 FT_Vector
* vec
= cur
->points
;
455 FT_Fixed x_scale
= glyph
->x_scale
;
456 FT_Fixed y_scale
= glyph
->y_scale
;
459 /* First of all, scale the points, if we are not hinting */
460 if ( !hinting
|| ! decoder
.builder
.hints_funcs
)
461 for ( n
= cur
->n_points
; n
> 0; n
--, vec
++ )
463 vec
->x
= FT_MulFix( vec
->x
, x_scale
);
464 vec
->y
= FT_MulFix( vec
->y
, y_scale
);
467 /* Then scale the metrics */
468 metrics
->horiAdvance
= FT_MulFix( metrics
->horiAdvance
, x_scale
);
469 metrics
->vertAdvance
= FT_MulFix( metrics
->vertAdvance
, y_scale
);
472 /* compute the other metrics */
473 FT_Outline_Get_CBox( &t1glyph
->outline
, &cbox
);
475 metrics
->width
= cbox
.xMax
- cbox
.xMin
;
476 metrics
->height
= cbox
.yMax
- cbox
.yMin
;
478 metrics
->horiBearingX
= cbox
.xMin
;
479 metrics
->horiBearingY
= cbox
.yMax
;
481 if ( load_flags
& FT_LOAD_VERTICAL_LAYOUT
)
483 /* make up vertical ones */
484 ft_synthesize_vertical_metrics( metrics
,
485 metrics
->vertAdvance
);
489 /* Set control data to the glyph charstrings. Note that this is */
490 /* _not_ zero-terminated. */
491 t1glyph
->control_data
= (FT_Byte
*)glyph_data
.pointer
;
492 t1glyph
->control_len
= glyph_data
.length
;
498 #ifdef FT_CONFIG_OPTION_INCREMENTAL
499 if ( glyph_data_loaded
&& face
->root
.internal
->incremental_interface
)
501 face
->root
.internal
->incremental_interface
->funcs
->free_glyph_data(
502 face
->root
.internal
->incremental_interface
->object
,
505 /* Set the control data to null - it is no longer available if */
506 /* loaded incrementally. */
507 t1glyph
->control_data
= 0;
508 t1glyph
->control_len
= 0;
512 if ( must_finish_decoder
)
513 decoder_funcs
->done( &decoder
);