1 /***************************************************************************/
5 /* Type 1 Glyph Loader (body). */
7 /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 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_DEBUG_H
22 #include FT_INTERNAL_STREAM_H
24 #include FT_INTERNAL_POSTSCRIPT_AUX_H
29 /*************************************************************************/
31 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
32 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
33 /* messages during execution. */
36 #define FT_COMPONENT trace_t1gload
39 /*************************************************************************/
40 /*************************************************************************/
41 /*************************************************************************/
42 /********** *********/
43 /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/
44 /********** *********/
45 /********** The following code is in charge of computing *********/
46 /********** the maximum advance width of the font. It *********/
47 /********** quickly processes each glyph charstring to *********/
48 /********** extract the value from either a `sbw' or `seac' *********/
49 /********** operator. *********/
50 /********** *********/
51 /*************************************************************************/
52 /*************************************************************************/
53 /*************************************************************************/
56 FT_LOCAL_DEF( FT_Error
)
57 T1_Parse_Glyph_And_Get_Char_String( T1_Decoder decoder
,
59 FT_Data
* char_string
)
61 T1_Face face
= (T1_Face
)decoder
->builder
.face
;
62 T1_Font type1
= &face
->type1
;
63 FT_Error error
= T1_Err_Ok
;
66 decoder
->font_matrix
= type1
->font_matrix
;
67 decoder
->font_offset
= type1
->font_offset
;
69 #ifdef FT_CONFIG_OPTION_INCREMENTAL
71 /* For incremental fonts get the character data using the */
72 /* callback function. */
73 if ( face
->root
.internal
->incremental_interface
)
74 error
= face
->root
.internal
->incremental_interface
->funcs
->get_glyph_data(
75 face
->root
.internal
->incremental_interface
->object
,
76 glyph_index
, char_string
);
79 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
81 /* For ordinary fonts get the character data stored in the face record. */
83 char_string
->pointer
= type1
->charstrings
[glyph_index
];
84 char_string
->length
= (FT_Int
)type1
->charstrings_len
[glyph_index
];
88 error
= decoder
->funcs
.parse_charstrings(
89 decoder
, (FT_Byte
*)char_string
->pointer
,
90 char_string
->length
);
92 #ifdef FT_CONFIG_OPTION_INCREMENTAL
94 /* Incremental fonts can optionally override the metrics. */
95 if ( !error
&& face
->root
.internal
->incremental_interface
&&
96 face
->root
.internal
->incremental_interface
->funcs
->get_glyph_metrics
)
98 FT_Incremental_MetricsRec metrics
;
101 metrics
.bearing_x
= decoder
->builder
.left_bearing
.x
;
102 metrics
.bearing_y
= decoder
->builder
.left_bearing
.y
;
103 metrics
.advance
= decoder
->builder
.advance
.x
;
104 error
= face
->root
.internal
->incremental_interface
->funcs
->get_glyph_metrics(
105 face
->root
.internal
->incremental_interface
->object
,
106 glyph_index
, FALSE
, &metrics
);
107 decoder
->builder
.left_bearing
.x
= metrics
.bearing_x
;
108 decoder
->builder
.left_bearing
.y
= metrics
.bearing_y
;
109 decoder
->builder
.advance
.x
= metrics
.advance
;
110 decoder
->builder
.advance
.y
= 0;
113 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
119 FT_CALLBACK_DEF( FT_Error
)
120 T1_Parse_Glyph( T1_Decoder decoder
,
121 FT_UInt glyph_index
)
124 FT_Error error
= T1_Parse_Glyph_And_Get_Char_String(
125 decoder
, glyph_index
, &glyph_data
);
128 #ifdef FT_CONFIG_OPTION_INCREMENTAL
132 T1_Face face
= (T1_Face
)decoder
->builder
.face
;
135 if ( face
->root
.internal
->incremental_interface
)
136 face
->root
.internal
->incremental_interface
->funcs
->free_glyph_data(
137 face
->root
.internal
->incremental_interface
->object
,
141 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
147 FT_LOCAL_DEF( FT_Error
)
148 T1_Compute_Max_Advance( T1_Face face
,
149 FT_Pos
* max_advance
)
152 T1_DecoderRec decoder
;
154 T1_Font type1
= &face
->type1
;
155 PSAux_Service psaux
= (PSAux_Service
)face
->psaux
;
158 FT_ASSERT( ( face
->len_buildchar
== 0 ) == ( face
->buildchar
== NULL
) );
162 /* initialize load decoder */
163 error
= psaux
->t1_decoder_funcs
->init( &decoder
,
167 (FT_Byte
**)type1
->glyph_names
,
170 FT_RENDER_MODE_NORMAL
,
175 decoder
.builder
.metrics_only
= 1;
176 decoder
.builder
.load_points
= 0;
178 decoder
.num_subrs
= type1
->num_subrs
;
179 decoder
.subrs
= type1
->subrs
;
180 decoder
.subrs_len
= type1
->subrs_len
;
182 decoder
.buildchar
= face
->buildchar
;
183 decoder
.len_buildchar
= face
->len_buildchar
;
187 /* for each glyph, parse the glyph charstring and extract */
188 /* the advance width */
189 for ( glyph_index
= 0; glyph_index
< type1
->num_glyphs
; glyph_index
++ )
191 /* now get load the unscaled outline */
192 error
= T1_Parse_Glyph( &decoder
, glyph_index
);
193 if ( glyph_index
== 0 || decoder
.builder
.advance
.x
> *max_advance
)
194 *max_advance
= decoder
.builder
.advance
.x
;
196 /* ignore the error if one occurred - skip to next glyph */
199 psaux
->t1_decoder_funcs
->done( &decoder
);
205 FT_LOCAL_DEF( FT_Error
)
206 T1_Load_Glyph( T1_GlyphSlot glyph
,
209 FT_Int32 load_flags
)
212 T1_DecoderRec decoder
;
213 T1_Face face
= (T1_Face
)glyph
->root
.face
;
215 T1_Font type1
= &face
->type1
;
216 PSAux_Service psaux
= (PSAux_Service
)face
->psaux
;
217 const T1_Decoder_Funcs decoder_funcs
= psaux
->t1_decoder_funcs
;
219 FT_Matrix font_matrix
;
220 FT_Vector font_offset
;
222 FT_Bool must_finish_decoder
= FALSE
;
223 #ifdef FT_CONFIG_OPTION_INCREMENTAL
224 FT_Bool glyph_data_loaded
= 0;
228 if ( glyph_index
>= (FT_UInt
)face
->root
.num_glyphs
)
230 error
= T1_Err_Invalid_Argument
;
234 FT_ASSERT( ( face
->len_buildchar
== 0 ) == ( face
->buildchar
== NULL
) );
236 if ( load_flags
& FT_LOAD_NO_RECURSE
)
237 load_flags
|= FT_LOAD_NO_SCALE
| FT_LOAD_NO_HINTING
;
239 glyph
->x_scale
= size
->root
.metrics
.x_scale
;
240 glyph
->y_scale
= size
->root
.metrics
.y_scale
;
242 glyph
->root
.outline
.n_points
= 0;
243 glyph
->root
.outline
.n_contours
= 0;
245 hinting
= FT_BOOL( ( load_flags
& FT_LOAD_NO_SCALE
) == 0 &&
246 ( load_flags
& FT_LOAD_NO_HINTING
) == 0 );
248 glyph
->root
.format
= FT_GLYPH_FORMAT_OUTLINE
;
250 error
= decoder_funcs
->init( &decoder
,
254 (FT_Byte
**)type1
->glyph_names
,
257 FT_LOAD_TARGET_MODE( load_flags
),
262 must_finish_decoder
= TRUE
;
264 decoder
.builder
.no_recurse
= FT_BOOL(
265 ( load_flags
& FT_LOAD_NO_RECURSE
) != 0 );
267 decoder
.num_subrs
= type1
->num_subrs
;
268 decoder
.subrs
= type1
->subrs
;
269 decoder
.subrs_len
= type1
->subrs_len
;
271 decoder
.buildchar
= face
->buildchar
;
272 decoder
.len_buildchar
= face
->len_buildchar
;
274 /* now load the unscaled outline */
275 error
= T1_Parse_Glyph_And_Get_Char_String( &decoder
, glyph_index
,
279 #ifdef FT_CONFIG_OPTION_INCREMENTAL
280 glyph_data_loaded
= 1;
283 font_matrix
= decoder
.font_matrix
;
284 font_offset
= decoder
.font_offset
;
286 /* save new glyph tables */
287 decoder_funcs
->done( &decoder
);
289 must_finish_decoder
= FALSE
;
291 /* now, set the metrics -- this is rather simple, as */
292 /* the left side bearing is the xMin, and the top side */
293 /* bearing the yMax */
296 glyph
->root
.outline
.flags
&= FT_OUTLINE_OWNER
;
297 glyph
->root
.outline
.flags
|= FT_OUTLINE_REVERSE_FILL
;
299 /* for composite glyphs, return only left side bearing and */
301 if ( load_flags
& FT_LOAD_NO_RECURSE
)
303 FT_Slot_Internal internal
= glyph
->root
.internal
;
306 glyph
->root
.metrics
.horiBearingX
= decoder
.builder
.left_bearing
.x
;
307 glyph
->root
.metrics
.horiAdvance
= decoder
.builder
.advance
.x
;
308 internal
->glyph_matrix
= font_matrix
;
309 internal
->glyph_delta
= font_offset
;
310 internal
->glyph_transformed
= 1;
315 FT_Glyph_Metrics
* metrics
= &glyph
->root
.metrics
;
319 /* copy the _unscaled_ advance width */
320 metrics
->horiAdvance
= decoder
.builder
.advance
.x
;
321 glyph
->root
.linearHoriAdvance
= decoder
.builder
.advance
.x
;
322 glyph
->root
.internal
->glyph_transformed
= 0;
324 /* make up vertical ones */
325 metrics
->vertAdvance
= ( face
->type1
.font_bbox
.yMax
-
326 face
->type1
.font_bbox
.yMin
) >> 16;
327 glyph
->root
.linearVertAdvance
= metrics
->vertAdvance
;
329 glyph
->root
.format
= FT_GLYPH_FORMAT_OUTLINE
;
331 if ( size
&& size
->root
.metrics
.y_ppem
< 24 )
332 glyph
->root
.outline
.flags
|= FT_OUTLINE_HIGH_PRECISION
;
335 /* apply the font matrix, if any */
336 if ( font_matrix
.xx
!= 0x10000L
|| font_matrix
.yy
!= font_matrix
.xx
||
337 font_matrix
.xy
!= 0 || font_matrix
.yx
!= 0 )
338 FT_Outline_Transform( &glyph
->root
.outline
, &font_matrix
);
340 if ( font_offset
.x
|| font_offset
.y
)
341 FT_Outline_Translate( &glyph
->root
.outline
,
345 advance
.x
= metrics
->horiAdvance
;
347 FT_Vector_Transform( &advance
, &font_matrix
);
348 metrics
->horiAdvance
= advance
.x
+ font_offset
.x
;
350 advance
.y
= metrics
->vertAdvance
;
351 FT_Vector_Transform( &advance
, &font_matrix
);
352 metrics
->vertAdvance
= advance
.y
+ font_offset
.y
;
355 if ( ( load_flags
& FT_LOAD_NO_SCALE
) == 0 )
357 /* scale the outline and the metrics */
359 FT_Outline
* cur
= decoder
.builder
.base
;
360 FT_Vector
* vec
= cur
->points
;
361 FT_Fixed x_scale
= glyph
->x_scale
;
362 FT_Fixed y_scale
= glyph
->y_scale
;
365 /* First of all, scale the points, if we are not hinting */
366 if ( !hinting
|| ! decoder
.builder
.hints_funcs
)
367 for ( n
= cur
->n_points
; n
> 0; n
--, vec
++ )
369 vec
->x
= FT_MulFix( vec
->x
, x_scale
);
370 vec
->y
= FT_MulFix( vec
->y
, y_scale
);
373 /* Then scale the metrics */
374 metrics
->horiAdvance
= FT_MulFix( metrics
->horiAdvance
, x_scale
);
375 metrics
->vertAdvance
= FT_MulFix( metrics
->vertAdvance
, y_scale
);
378 /* compute the other metrics */
379 FT_Outline_Get_CBox( &glyph
->root
.outline
, &cbox
);
381 metrics
->width
= cbox
.xMax
- cbox
.xMin
;
382 metrics
->height
= cbox
.yMax
- cbox
.yMin
;
384 metrics
->horiBearingX
= cbox
.xMin
;
385 metrics
->horiBearingY
= cbox
.yMax
;
387 /* make up vertical ones */
388 ft_synthesize_vertical_metrics( metrics
,
389 metrics
->vertAdvance
);
392 /* Set control data to the glyph charstrings. Note that this is */
393 /* _not_ zero-terminated. */
394 glyph
->root
.control_data
= (FT_Byte
*)glyph_data
.pointer
;
395 glyph
->root
.control_len
= glyph_data
.length
;
401 #ifdef FT_CONFIG_OPTION_INCREMENTAL
402 if ( glyph_data_loaded
&& face
->root
.internal
->incremental_interface
)
404 face
->root
.internal
->incremental_interface
->funcs
->free_glyph_data(
405 face
->root
.internal
->incremental_interface
->object
,
408 /* Set the control data to null - it is no longer available if */
409 /* loaded incrementally. */
410 glyph
->root
.control_data
= 0;
411 glyph
->root
.control_len
= 0;
415 if ( must_finish_decoder
)
416 decoder_funcs
->done( &decoder
);