1 /***************************************************************************/
5 /* Type 1 Glyph Loader (body). */
7 /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010 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
= T1_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( T1_Face face
,
217 T1_DecoderRec decoder
;
218 T1_Font type1
= &face
->type1
;
219 PSAux_Service psaux
= (PSAux_Service
)face
->psaux
;
224 if ( load_flags
& FT_LOAD_VERTICAL_LAYOUT
)
226 for ( nn
= 0; nn
< count
; nn
++ )
232 error
= psaux
->t1_decoder_funcs
->init( &decoder
,
236 (FT_Byte
**)type1
->glyph_names
,
239 FT_RENDER_MODE_NORMAL
,
244 decoder
.builder
.metrics_only
= 1;
245 decoder
.builder
.load_points
= 0;
247 decoder
.num_subrs
= type1
->num_subrs
;
248 decoder
.subrs
= type1
->subrs
;
249 decoder
.subrs_len
= type1
->subrs_len
;
251 decoder
.buildchar
= face
->buildchar
;
252 decoder
.len_buildchar
= face
->len_buildchar
;
254 for ( nn
= 0; nn
< count
; nn
++ )
256 error
= T1_Parse_Glyph( &decoder
, first
+ nn
);
258 advances
[nn
] = FIXED_TO_INT( decoder
.builder
.advance
.x
);
267 FT_LOCAL_DEF( FT_Error
)
268 T1_Load_Glyph( T1_GlyphSlot glyph
,
271 FT_Int32 load_flags
)
274 T1_DecoderRec decoder
;
275 T1_Face face
= (T1_Face
)glyph
->root
.face
;
277 T1_Font type1
= &face
->type1
;
278 PSAux_Service psaux
= (PSAux_Service
)face
->psaux
;
279 const T1_Decoder_Funcs decoder_funcs
= psaux
->t1_decoder_funcs
;
281 FT_Matrix font_matrix
;
282 FT_Vector font_offset
;
284 FT_Bool must_finish_decoder
= FALSE
;
285 #ifdef FT_CONFIG_OPTION_INCREMENTAL
286 FT_Bool glyph_data_loaded
= 0;
290 #ifdef FT_CONFIG_OPTION_INCREMENTAL
291 if ( glyph_index
>= (FT_UInt
)face
->root
.num_glyphs
&&
292 !face
->root
.internal
->incremental_interface
)
294 if ( glyph_index
>= (FT_UInt
)face
->root
.num_glyphs
)
295 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
297 error
= T1_Err_Invalid_Argument
;
301 FT_ASSERT( ( face
->len_buildchar
== 0 ) == ( face
->buildchar
== NULL
) );
303 if ( load_flags
& FT_LOAD_NO_RECURSE
)
304 load_flags
|= FT_LOAD_NO_SCALE
| FT_LOAD_NO_HINTING
;
308 glyph
->x_scale
= size
->root
.metrics
.x_scale
;
309 glyph
->y_scale
= size
->root
.metrics
.y_scale
;
313 glyph
->x_scale
= 0x10000L
;
314 glyph
->y_scale
= 0x10000L
;
317 glyph
->root
.outline
.n_points
= 0;
318 glyph
->root
.outline
.n_contours
= 0;
320 hinting
= FT_BOOL( ( load_flags
& FT_LOAD_NO_SCALE
) == 0 &&
321 ( load_flags
& FT_LOAD_NO_HINTING
) == 0 );
323 glyph
->root
.format
= FT_GLYPH_FORMAT_OUTLINE
;
325 error
= decoder_funcs
->init( &decoder
,
329 (FT_Byte
**)type1
->glyph_names
,
332 FT_LOAD_TARGET_MODE( load_flags
),
337 must_finish_decoder
= TRUE
;
339 decoder
.builder
.no_recurse
= FT_BOOL(
340 ( load_flags
& FT_LOAD_NO_RECURSE
) != 0 );
342 decoder
.num_subrs
= type1
->num_subrs
;
343 decoder
.subrs
= type1
->subrs
;
344 decoder
.subrs_len
= type1
->subrs_len
;
346 decoder
.buildchar
= face
->buildchar
;
347 decoder
.len_buildchar
= face
->len_buildchar
;
349 /* now load the unscaled outline */
350 error
= T1_Parse_Glyph_And_Get_Char_String( &decoder
, glyph_index
,
354 #ifdef FT_CONFIG_OPTION_INCREMENTAL
355 glyph_data_loaded
= 1;
358 font_matrix
= decoder
.font_matrix
;
359 font_offset
= decoder
.font_offset
;
361 /* save new glyph tables */
362 decoder_funcs
->done( &decoder
);
364 must_finish_decoder
= FALSE
;
366 /* now, set the metrics -- this is rather simple, as */
367 /* the left side bearing is the xMin, and the top side */
368 /* bearing the yMax */
371 glyph
->root
.outline
.flags
&= FT_OUTLINE_OWNER
;
372 glyph
->root
.outline
.flags
|= FT_OUTLINE_REVERSE_FILL
;
374 /* for composite glyphs, return only left side bearing and */
376 if ( load_flags
& FT_LOAD_NO_RECURSE
)
378 FT_Slot_Internal internal
= glyph
->root
.internal
;
381 glyph
->root
.metrics
.horiBearingX
=
382 FIXED_TO_INT( decoder
.builder
.left_bearing
.x
);
383 glyph
->root
.metrics
.horiAdvance
=
384 FIXED_TO_INT( decoder
.builder
.advance
.x
);
386 internal
->glyph_matrix
= font_matrix
;
387 internal
->glyph_delta
= font_offset
;
388 internal
->glyph_transformed
= 1;
393 FT_Glyph_Metrics
* metrics
= &glyph
->root
.metrics
;
397 /* copy the _unscaled_ advance width */
398 metrics
->horiAdvance
=
399 FIXED_TO_INT( decoder
.builder
.advance
.x
);
400 glyph
->root
.linearHoriAdvance
=
401 FIXED_TO_INT( decoder
.builder
.advance
.x
);
402 glyph
->root
.internal
->glyph_transformed
= 0;
404 if ( load_flags
& FT_LOAD_VERTICAL_LAYOUT
)
406 /* make up vertical ones */
407 metrics
->vertAdvance
= ( face
->type1
.font_bbox
.yMax
-
408 face
->type1
.font_bbox
.yMin
) >> 16;
409 glyph
->root
.linearVertAdvance
= metrics
->vertAdvance
;
413 metrics
->vertAdvance
=
414 FIXED_TO_INT( decoder
.builder
.advance
.y
);
415 glyph
->root
.linearVertAdvance
=
416 FIXED_TO_INT( decoder
.builder
.advance
.y
);
419 glyph
->root
.format
= FT_GLYPH_FORMAT_OUTLINE
;
421 if ( size
&& size
->root
.metrics
.y_ppem
< 24 )
422 glyph
->root
.outline
.flags
|= FT_OUTLINE_HIGH_PRECISION
;
425 /* apply the font matrix, if any */
426 if ( font_matrix
.xx
!= 0x10000L
|| font_matrix
.yy
!= font_matrix
.xx
||
427 font_matrix
.xy
!= 0 || font_matrix
.yx
!= 0 )
428 FT_Outline_Transform( &glyph
->root
.outline
, &font_matrix
);
430 if ( font_offset
.x
|| font_offset
.y
)
431 FT_Outline_Translate( &glyph
->root
.outline
,
435 advance
.x
= metrics
->horiAdvance
;
437 FT_Vector_Transform( &advance
, &font_matrix
);
438 metrics
->horiAdvance
= advance
.x
+ font_offset
.x
;
440 advance
.y
= metrics
->vertAdvance
;
441 FT_Vector_Transform( &advance
, &font_matrix
);
442 metrics
->vertAdvance
= advance
.y
+ font_offset
.y
;
445 if ( ( load_flags
& FT_LOAD_NO_SCALE
) == 0 )
447 /* scale the outline and the metrics */
449 FT_Outline
* cur
= decoder
.builder
.base
;
450 FT_Vector
* vec
= cur
->points
;
451 FT_Fixed x_scale
= glyph
->x_scale
;
452 FT_Fixed y_scale
= glyph
->y_scale
;
455 /* First of all, scale the points, if we are not hinting */
456 if ( !hinting
|| ! decoder
.builder
.hints_funcs
)
457 for ( n
= cur
->n_points
; n
> 0; n
--, vec
++ )
459 vec
->x
= FT_MulFix( vec
->x
, x_scale
);
460 vec
->y
= FT_MulFix( vec
->y
, y_scale
);
463 /* Then scale the metrics */
464 metrics
->horiAdvance
= FT_MulFix( metrics
->horiAdvance
, x_scale
);
465 metrics
->vertAdvance
= FT_MulFix( metrics
->vertAdvance
, y_scale
);
468 /* compute the other metrics */
469 FT_Outline_Get_CBox( &glyph
->root
.outline
, &cbox
);
471 metrics
->width
= cbox
.xMax
- cbox
.xMin
;
472 metrics
->height
= cbox
.yMax
- cbox
.yMin
;
474 metrics
->horiBearingX
= cbox
.xMin
;
475 metrics
->horiBearingY
= cbox
.yMax
;
477 if ( load_flags
& FT_LOAD_VERTICAL_LAYOUT
)
479 /* make up vertical ones */
480 ft_synthesize_vertical_metrics( metrics
,
481 metrics
->vertAdvance
);
485 /* Set control data to the glyph charstrings. Note that this is */
486 /* _not_ zero-terminated. */
487 glyph
->root
.control_data
= (FT_Byte
*)glyph_data
.pointer
;
488 glyph
->root
.control_len
= glyph_data
.length
;
494 #ifdef FT_CONFIG_OPTION_INCREMENTAL
495 if ( glyph_data_loaded
&& face
->root
.internal
->incremental_interface
)
497 face
->root
.internal
->incremental_interface
->funcs
->free_glyph_data(
498 face
->root
.internal
->incremental_interface
->object
,
501 /* Set the control data to null - it is no longer available if */
502 /* loaded incrementally. */
503 glyph
->root
.control_data
= 0;
504 glyph
->root
.control_len
= 0;
508 if ( must_finish_decoder
)
509 decoder_funcs
->done( &decoder
);