1 /***************************************************************************/
5 /* CID-keyed Type1 Glyph Loader (body). */
7 /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 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 /***************************************************************************/
22 #include FT_INTERNAL_DEBUG_H
23 #include FT_INTERNAL_STREAM_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_cidgload
39 FT_CALLBACK_DEF( FT_Error
)
40 cid_load_glyph( T1_Decoder decoder
,
43 CID_Face face
= (CID_Face
)decoder
->builder
.face
;
44 CID_FaceInfo cid
= &face
->cid
;
47 FT_Stream stream
= face
->cid_stream
;
48 FT_Error error
= CID_Err_Ok
;
49 FT_Byte
* charstring
= 0;
50 FT_Memory memory
= face
->root
.memory
;
51 FT_ULong glyph_length
= 0;
52 PSAux_Service psaux
= (PSAux_Service
)face
->psaux
;
55 #ifdef FT_CONFIG_OPTION_INCREMENTAL
57 /* For incremental fonts get the character data using */
58 /* the callback function. */
59 if ( face
->root
.internal
->incremental_interface
)
64 error
= face
->root
.internal
->incremental_interface
->funcs
->get_glyph_data(
65 face
->root
.internal
->incremental_interface
->object
,
71 p
= (FT_Byte
*)glyph_data
.pointer
;
72 fd_select
= (FT_UInt
)cid_get_offset( &p
, (FT_Byte
)cid
->fd_bytes
);
74 if ( glyph_data
.length
!= 0 )
76 glyph_length
= glyph_data
.length
- cid
->fd_bytes
;
77 FT_ALLOC( charstring
, glyph_length
);
79 ft_memcpy( charstring
, glyph_data
.pointer
+ cid
->fd_bytes
,
83 face
->root
.internal
->incremental_interface
->funcs
->free_glyph_data(
84 face
->root
.internal
->incremental_interface
->object
,
93 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
95 /* For ordinary fonts read the CID font dictionary index */
96 /* and charstring offset from the CIDMap. */
98 FT_UInt entry_len
= cid
->fd_bytes
+ cid
->gd_bytes
;
102 if ( FT_STREAM_SEEK( cid
->data_offset
+ cid
->cidmap_offset
+
103 glyph_index
* entry_len
) ||
104 FT_FRAME_ENTER( 2 * entry_len
) )
107 p
= (FT_Byte
*)stream
->cursor
;
108 fd_select
= (FT_UInt
) cid_get_offset( &p
, (FT_Byte
)cid
->fd_bytes
);
109 off1
= (FT_ULong
)cid_get_offset( &p
, (FT_Byte
)cid
->gd_bytes
);
111 glyph_length
= cid_get_offset( &p
, (FT_Byte
)cid
->gd_bytes
) - off1
;
114 if ( fd_select
>= (FT_UInt
)cid
->num_dicts
)
116 error
= CID_Err_Invalid_Offset
;
119 if ( glyph_length
== 0 )
121 if ( FT_ALLOC( charstring
, glyph_length
) )
123 if ( FT_STREAM_READ_AT( cid
->data_offset
+ off1
,
124 charstring
, glyph_length
) )
128 /* Now set up the subrs array and parse the charstrings. */
131 CID_Subrs cid_subrs
= face
->subrs
+ fd_select
;
136 decoder
->num_subrs
= cid_subrs
->num_subrs
;
137 decoder
->subrs
= cid_subrs
->code
;
138 decoder
->subrs_len
= 0;
140 /* Set up font matrix */
141 dict
= cid
->font_dicts
+ fd_select
;
143 decoder
->font_matrix
= dict
->font_matrix
;
144 decoder
->font_offset
= dict
->font_offset
;
145 decoder
->lenIV
= dict
->private_dict
.lenIV
;
147 /* Decode the charstring. */
149 /* Adjustment for seed bytes. */
150 cs_offset
= ( decoder
->lenIV
>= 0 ? decoder
->lenIV
: 0 );
152 /* Decrypt only if lenIV >= 0. */
153 if ( decoder
->lenIV
>= 0 )
154 psaux
->t1_decrypt( charstring
, glyph_length
, 4330 );
156 error
= decoder
->funcs
.parse_charstrings(
157 decoder
, charstring
+ cs_offset
,
158 (FT_Int
)glyph_length
- cs_offset
);
161 FT_FREE( charstring
);
163 #ifdef FT_CONFIG_OPTION_INCREMENTAL
165 /* Incremental fonts can optionally override the metrics. */
167 face
->root
.internal
->incremental_interface
&&
168 face
->root
.internal
->incremental_interface
->funcs
->get_glyph_metrics
)
170 FT_Incremental_MetricsRec metrics
;
173 metrics
.bearing_x
= decoder
->builder
.left_bearing
.x
;
174 metrics
.bearing_y
= decoder
->builder
.left_bearing
.y
;
175 metrics
.advance
= decoder
->builder
.advance
.x
;
176 error
= face
->root
.internal
->incremental_interface
->funcs
->get_glyph_metrics(
177 face
->root
.internal
->incremental_interface
->object
,
178 glyph_index
, FALSE
, &metrics
);
179 decoder
->builder
.left_bearing
.x
= metrics
.bearing_x
;
180 decoder
->builder
.left_bearing
.y
= metrics
.bearing_y
;
181 decoder
->builder
.advance
.x
= metrics
.advance
;
182 decoder
->builder
.advance
.y
= 0;
185 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
195 /*************************************************************************/
196 /*************************************************************************/
197 /*************************************************************************/
198 /********** *********/
199 /********** *********/
200 /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/
201 /********** *********/
202 /********** The following code is in charge of computing *********/
203 /********** the maximum advance width of the font. It *********/
204 /********** quickly processes each glyph charstring to *********/
205 /********** extract the value from either a `sbw' or `seac' *********/
206 /********** operator. *********/
207 /********** *********/
208 /*************************************************************************/
209 /*************************************************************************/
210 /*************************************************************************/
213 FT_LOCAL_DEF( FT_Error
)
214 cid_face_compute_max_advance( CID_Face face
,
215 FT_Int
* max_advance
)
218 T1_DecoderRec decoder
;
221 PSAux_Service psaux
= (PSAux_Service
)face
->psaux
;
226 /* Initialize load decoder */
227 error
= psaux
->t1_decoder_funcs
->init( &decoder
,
231 0, /* glyph names! XXX */
233 0, /* hinting == 0 */
238 /* TODO: initialize decoder.len_buildchar and decoder.buildchar */
239 /* if we ever support CID-keyed multiple master fonts */
241 decoder
.builder
.metrics_only
= 1;
242 decoder
.builder
.load_points
= 0;
244 /* for each glyph, parse the glyph charstring and extract */
245 /* the advance width */
246 for ( glyph_index
= 0; glyph_index
< face
->root
.num_glyphs
;
249 /* now get load the unscaled outline */
250 error
= cid_load_glyph( &decoder
, glyph_index
);
251 /* ignore the error if one occurred - skip to next glyph */
254 *max_advance
= decoder
.builder
.advance
.x
;
256 psaux
->t1_decoder_funcs
->done( &decoder
);
265 FT_LOCAL_DEF( FT_Error
)
266 cid_slot_load_glyph( FT_GlyphSlot cidglyph
, /* CID_GlyphSlot */
267 FT_Size cidsize
, /* CID_Size */
269 FT_Int32 load_flags
)
271 CID_GlyphSlot glyph
= (CID_GlyphSlot
)cidglyph
;
272 CID_Size size
= (CID_Size
)cidsize
;
274 T1_DecoderRec decoder
;
275 CID_Face face
= (CID_Face
)cidglyph
->face
;
278 PSAux_Service psaux
= (PSAux_Service
)face
->psaux
;
279 FT_Matrix font_matrix
;
280 FT_Vector font_offset
;
283 if ( glyph_index
>= (FT_UInt
)face
->root
.num_glyphs
)
285 error
= CID_Err_Invalid_Argument
;
289 if ( load_flags
& FT_LOAD_NO_RECURSE
)
290 load_flags
|= FT_LOAD_NO_SCALE
| FT_LOAD_NO_HINTING
;
292 glyph
->x_scale
= cidsize
->metrics
.x_scale
;
293 glyph
->y_scale
= cidsize
->metrics
.y_scale
;
295 cidglyph
->outline
.n_points
= 0;
296 cidglyph
->outline
.n_contours
= 0;
298 hinting
= FT_BOOL( ( load_flags
& FT_LOAD_NO_SCALE
) == 0 &&
299 ( load_flags
& FT_LOAD_NO_HINTING
) == 0 );
301 cidglyph
->format
= FT_GLYPH_FORMAT_OUTLINE
;
303 error
= psaux
->t1_decoder_funcs
->init( &decoder
,
307 0, /* glyph names -- XXX */
310 FT_LOAD_TARGET_MODE( load_flags
),
315 /* TODO: initialize decoder.len_buildchar and decoder.buildchar */
316 /* if we ever support CID-keyed multiple master fonts */
318 /* set up the decoder */
319 decoder
.builder
.no_recurse
= FT_BOOL(
320 ( ( load_flags
& FT_LOAD_NO_RECURSE
) != 0 ) );
322 error
= cid_load_glyph( &decoder
, glyph_index
);
326 font_matrix
= decoder
.font_matrix
;
327 font_offset
= decoder
.font_offset
;
329 /* save new glyph tables */
330 psaux
->t1_decoder_funcs
->done( &decoder
);
332 /* now set the metrics -- this is rather simple, as */
333 /* the left side bearing is the xMin, and the top side */
334 /* bearing the yMax */
335 cidglyph
->outline
.flags
&= FT_OUTLINE_OWNER
;
336 cidglyph
->outline
.flags
|= FT_OUTLINE_REVERSE_FILL
;
338 /* for composite glyphs, return only left side bearing and */
340 if ( load_flags
& FT_LOAD_NO_RECURSE
)
342 FT_Slot_Internal internal
= cidglyph
->internal
;
345 cidglyph
->metrics
.horiBearingX
= decoder
.builder
.left_bearing
.x
;
346 cidglyph
->metrics
.horiAdvance
= decoder
.builder
.advance
.x
;
348 internal
->glyph_matrix
= font_matrix
;
349 internal
->glyph_delta
= font_offset
;
350 internal
->glyph_transformed
= 1;
355 FT_Glyph_Metrics
* metrics
= &cidglyph
->metrics
;
359 /* copy the _unscaled_ advance width */
360 metrics
->horiAdvance
= decoder
.builder
.advance
.x
;
361 cidglyph
->linearHoriAdvance
= decoder
.builder
.advance
.x
;
362 cidglyph
->internal
->glyph_transformed
= 0;
364 /* make up vertical ones */
365 metrics
->vertAdvance
= ( face
->cid
.font_bbox
.yMax
-
366 face
->cid
.font_bbox
.yMin
) >> 16;
367 cidglyph
->linearVertAdvance
= metrics
->vertAdvance
;
369 cidglyph
->format
= FT_GLYPH_FORMAT_OUTLINE
;
371 if ( size
&& cidsize
->metrics
.y_ppem
< 24 )
372 cidglyph
->outline
.flags
|= FT_OUTLINE_HIGH_PRECISION
;
374 /* apply the font matrix */
375 FT_Outline_Transform( &cidglyph
->outline
, &font_matrix
);
377 FT_Outline_Translate( &cidglyph
->outline
,
381 advance
.x
= metrics
->horiAdvance
;
383 FT_Vector_Transform( &advance
, &font_matrix
);
384 metrics
->horiAdvance
= advance
.x
+ font_offset
.x
;
387 advance
.y
= metrics
->vertAdvance
;
388 FT_Vector_Transform( &advance
, &font_matrix
);
389 metrics
->vertAdvance
= advance
.y
+ font_offset
.y
;
391 if ( ( load_flags
& FT_LOAD_NO_SCALE
) == 0 )
393 /* scale the outline and the metrics */
395 FT_Outline
* cur
= decoder
.builder
.base
;
396 FT_Vector
* vec
= cur
->points
;
397 FT_Fixed x_scale
= glyph
->x_scale
;
398 FT_Fixed y_scale
= glyph
->y_scale
;
401 /* First of all, scale the points */
402 if ( !hinting
|| !decoder
.builder
.hints_funcs
)
403 for ( n
= cur
->n_points
; n
> 0; n
--, vec
++ )
405 vec
->x
= FT_MulFix( vec
->x
, x_scale
);
406 vec
->y
= FT_MulFix( vec
->y
, y_scale
);
409 /* Then scale the metrics */
410 metrics
->horiAdvance
= FT_MulFix( metrics
->horiAdvance
, x_scale
);
411 metrics
->vertAdvance
= FT_MulFix( metrics
->vertAdvance
, y_scale
);
414 /* compute the other metrics */
415 FT_Outline_Get_CBox( &cidglyph
->outline
, &cbox
);
417 metrics
->width
= cbox
.xMax
- cbox
.xMin
;
418 metrics
->height
= cbox
.yMax
- cbox
.yMin
;
420 metrics
->horiBearingX
= cbox
.xMin
;
421 metrics
->horiBearingY
= cbox
.yMax
;
423 /* make up vertical ones */
424 ft_synthesize_vertical_metrics( metrics
,
425 metrics
->vertAdvance
);