1 /***************************************************************************/
5 /* CID-keyed Type1 Glyph Loader (body). */
7 /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 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 /***************************************************************************/
22 #include FT_INTERNAL_DEBUG_H
23 #include FT_INTERNAL_STREAM_H
25 #include FT_INTERNAL_CALC_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_cidgload
40 FT_CALLBACK_DEF( FT_Error
)
41 cid_load_glyph( T1_Decoder decoder
,
44 CID_Face face
= (CID_Face
)decoder
->builder
.face
;
45 CID_FaceInfo cid
= &face
->cid
;
48 FT_Stream stream
= face
->cid_stream
;
49 FT_Error error
= CID_Err_Ok
;
50 FT_Byte
* charstring
= 0;
51 FT_Memory memory
= face
->root
.memory
;
52 FT_ULong glyph_length
= 0;
53 PSAux_Service psaux
= (PSAux_Service
)face
->psaux
;
55 #ifdef FT_CONFIG_OPTION_INCREMENTAL
56 FT_Incremental_InterfaceRec
*inc
=
57 face
->root
.internal
->incremental_interface
;
61 FT_TRACE4(( "cid_load_glyph: glyph index %d\n", glyph_index
));
63 #ifdef FT_CONFIG_OPTION_INCREMENTAL
65 /* For incremental fonts get the character data using */
66 /* the callback function. */
72 error
= inc
->funcs
->get_glyph_data( inc
->object
,
73 glyph_index
, &glyph_data
);
77 p
= (FT_Byte
*)glyph_data
.pointer
;
78 fd_select
= (FT_UInt
)cid_get_offset( &p
, (FT_Byte
)cid
->fd_bytes
);
80 if ( glyph_data
.length
!= 0 )
82 glyph_length
= glyph_data
.length
- cid
->fd_bytes
;
83 (void)FT_ALLOC( charstring
, glyph_length
);
85 ft_memcpy( charstring
, glyph_data
.pointer
+ cid
->fd_bytes
,
89 inc
->funcs
->free_glyph_data( inc
->object
, &glyph_data
);
97 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
99 /* For ordinary fonts read the CID font dictionary index */
100 /* and charstring offset from the CIDMap. */
102 FT_UInt entry_len
= cid
->fd_bytes
+ cid
->gd_bytes
;
106 if ( FT_STREAM_SEEK( cid
->data_offset
+ cid
->cidmap_offset
+
107 glyph_index
* entry_len
) ||
108 FT_FRAME_ENTER( 2 * entry_len
) )
111 p
= (FT_Byte
*)stream
->cursor
;
112 fd_select
= (FT_UInt
) cid_get_offset( &p
, (FT_Byte
)cid
->fd_bytes
);
113 off1
= (FT_ULong
)cid_get_offset( &p
, (FT_Byte
)cid
->gd_bytes
);
115 glyph_length
= cid_get_offset( &p
, (FT_Byte
)cid
->gd_bytes
) - off1
;
118 if ( fd_select
>= (FT_UInt
)cid
->num_dicts
)
120 error
= CID_Err_Invalid_Offset
;
123 if ( glyph_length
== 0 )
125 if ( FT_ALLOC( charstring
, glyph_length
) )
127 if ( FT_STREAM_READ_AT( cid
->data_offset
+ off1
,
128 charstring
, glyph_length
) )
132 /* Now set up the subrs array and parse the charstrings. */
135 CID_Subrs cid_subrs
= face
->subrs
+ fd_select
;
140 decoder
->num_subrs
= cid_subrs
->num_subrs
;
141 decoder
->subrs
= cid_subrs
->code
;
142 decoder
->subrs_len
= 0;
144 /* Set up font matrix */
145 dict
= cid
->font_dicts
+ fd_select
;
147 decoder
->font_matrix
= dict
->font_matrix
;
148 decoder
->font_offset
= dict
->font_offset
;
149 decoder
->lenIV
= dict
->private_dict
.lenIV
;
151 /* Decode the charstring. */
153 /* Adjustment for seed bytes. */
154 cs_offset
= ( decoder
->lenIV
>= 0 ? decoder
->lenIV
: 0 );
156 /* Decrypt only if lenIV >= 0. */
157 if ( decoder
->lenIV
>= 0 )
158 psaux
->t1_decrypt( charstring
, glyph_length
, 4330 );
160 error
= decoder
->funcs
.parse_charstrings(
161 decoder
, charstring
+ cs_offset
,
162 (FT_Int
)glyph_length
- cs_offset
);
165 FT_FREE( charstring
);
167 #ifdef FT_CONFIG_OPTION_INCREMENTAL
169 /* Incremental fonts can optionally override the metrics. */
170 if ( !error
&& inc
&& inc
->funcs
->get_glyph_metrics
)
172 FT_Incremental_MetricsRec metrics
;
175 metrics
.bearing_x
= FIXED_TO_INT( decoder
->builder
.left_bearing
.x
);
176 metrics
.bearing_y
= 0;
177 metrics
.advance
= FIXED_TO_INT( decoder
->builder
.advance
.x
);
178 metrics
.advance_v
= FIXED_TO_INT( decoder
->builder
.advance
.y
);
180 error
= inc
->funcs
->get_glyph_metrics( inc
->object
,
181 glyph_index
, FALSE
, &metrics
);
183 decoder
->builder
.left_bearing
.x
= INT_TO_FIXED( metrics
.bearing_x
);
184 decoder
->builder
.advance
.x
= INT_TO_FIXED( metrics
.advance
);
185 decoder
->builder
.advance
.y
= INT_TO_FIXED( metrics
.advance_v
);
188 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
198 /*************************************************************************/
199 /*************************************************************************/
200 /*************************************************************************/
201 /********** *********/
202 /********** *********/
203 /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/
204 /********** *********/
205 /********** The following code is in charge of computing *********/
206 /********** the maximum advance width of the font. It *********/
207 /********** quickly processes each glyph charstring to *********/
208 /********** extract the value from either a `sbw' or `seac' *********/
209 /********** operator. *********/
210 /********** *********/
211 /*************************************************************************/
212 /*************************************************************************/
213 /*************************************************************************/
216 FT_LOCAL_DEF( FT_Error
)
217 cid_face_compute_max_advance( CID_Face face
,
218 FT_Int
* max_advance
)
221 T1_DecoderRec decoder
;
224 PSAux_Service psaux
= (PSAux_Service
)face
->psaux
;
229 /* Initialize load decoder */
230 error
= psaux
->t1_decoder_funcs
->init( &decoder
,
234 0, /* glyph names! XXX */
236 0, /* hinting == 0 */
241 /* TODO: initialize decoder.len_buildchar and decoder.buildchar */
242 /* if we ever support CID-keyed multiple master fonts */
244 decoder
.builder
.metrics_only
= 1;
245 decoder
.builder
.load_points
= 0;
247 /* for each glyph, parse the glyph charstring and extract */
248 /* the advance width */
249 for ( glyph_index
= 0; glyph_index
< face
->root
.num_glyphs
;
252 /* now get load the unscaled outline */
253 error
= cid_load_glyph( &decoder
, glyph_index
);
254 /* ignore the error if one occurred - skip to next glyph */
257 *max_advance
= FIXED_TO_INT( decoder
.builder
.advance
.x
);
259 psaux
->t1_decoder_funcs
->done( &decoder
);
268 FT_LOCAL_DEF( FT_Error
)
269 cid_slot_load_glyph( FT_GlyphSlot cidglyph
, /* CID_GlyphSlot */
270 FT_Size cidsize
, /* CID_Size */
272 FT_Int32 load_flags
)
274 CID_GlyphSlot glyph
= (CID_GlyphSlot
)cidglyph
;
275 CID_Size size
= (CID_Size
)cidsize
;
277 T1_DecoderRec decoder
;
278 CID_Face face
= (CID_Face
)cidglyph
->face
;
281 PSAux_Service psaux
= (PSAux_Service
)face
->psaux
;
282 FT_Matrix font_matrix
;
283 FT_Vector font_offset
;
286 if ( glyph_index
>= (FT_UInt
)face
->root
.num_glyphs
)
288 error
= CID_Err_Invalid_Argument
;
292 if ( load_flags
& FT_LOAD_NO_RECURSE
)
293 load_flags
|= FT_LOAD_NO_SCALE
| FT_LOAD_NO_HINTING
;
295 glyph
->x_scale
= cidsize
->metrics
.x_scale
;
296 glyph
->y_scale
= cidsize
->metrics
.y_scale
;
298 cidglyph
->outline
.n_points
= 0;
299 cidglyph
->outline
.n_contours
= 0;
301 hinting
= FT_BOOL( ( load_flags
& FT_LOAD_NO_SCALE
) == 0 &&
302 ( load_flags
& FT_LOAD_NO_HINTING
) == 0 );
304 cidglyph
->format
= FT_GLYPH_FORMAT_OUTLINE
;
306 error
= psaux
->t1_decoder_funcs
->init( &decoder
,
310 0, /* glyph names -- XXX */
313 FT_LOAD_TARGET_MODE( load_flags
),
318 /* TODO: initialize decoder.len_buildchar and decoder.buildchar */
319 /* if we ever support CID-keyed multiple master fonts */
321 /* set up the decoder */
322 decoder
.builder
.no_recurse
= FT_BOOL(
323 ( ( load_flags
& FT_LOAD_NO_RECURSE
) != 0 ) );
325 error
= cid_load_glyph( &decoder
, glyph_index
);
329 font_matrix
= decoder
.font_matrix
;
330 font_offset
= decoder
.font_offset
;
332 /* save new glyph tables */
333 psaux
->t1_decoder_funcs
->done( &decoder
);
335 /* now set the metrics -- this is rather simple, as */
336 /* the left side bearing is the xMin, and the top side */
337 /* bearing the yMax */
338 cidglyph
->outline
.flags
&= FT_OUTLINE_OWNER
;
339 cidglyph
->outline
.flags
|= FT_OUTLINE_REVERSE_FILL
;
341 /* for composite glyphs, return only left side bearing and */
343 if ( load_flags
& FT_LOAD_NO_RECURSE
)
345 FT_Slot_Internal internal
= cidglyph
->internal
;
348 cidglyph
->metrics
.horiBearingX
=
349 FIXED_TO_INT( decoder
.builder
.left_bearing
.x
);
350 cidglyph
->metrics
.horiAdvance
=
351 FIXED_TO_INT( decoder
.builder
.advance
.x
);
353 internal
->glyph_matrix
= font_matrix
;
354 internal
->glyph_delta
= font_offset
;
355 internal
->glyph_transformed
= 1;
360 FT_Glyph_Metrics
* metrics
= &cidglyph
->metrics
;
364 /* copy the _unscaled_ advance width */
365 metrics
->horiAdvance
=
366 FIXED_TO_INT( decoder
.builder
.advance
.x
);
367 cidglyph
->linearHoriAdvance
=
368 FIXED_TO_INT( decoder
.builder
.advance
.x
);
369 cidglyph
->internal
->glyph_transformed
= 0;
371 /* make up vertical ones */
372 metrics
->vertAdvance
= ( face
->cid
.font_bbox
.yMax
-
373 face
->cid
.font_bbox
.yMin
) >> 16;
374 cidglyph
->linearVertAdvance
= metrics
->vertAdvance
;
376 cidglyph
->format
= FT_GLYPH_FORMAT_OUTLINE
;
378 if ( size
&& cidsize
->metrics
.y_ppem
< 24 )
379 cidglyph
->outline
.flags
|= FT_OUTLINE_HIGH_PRECISION
;
381 /* apply the font matrix */
382 FT_Outline_Transform( &cidglyph
->outline
, &font_matrix
);
384 FT_Outline_Translate( &cidglyph
->outline
,
388 advance
.x
= metrics
->horiAdvance
;
390 FT_Vector_Transform( &advance
, &font_matrix
);
391 metrics
->horiAdvance
= advance
.x
+ font_offset
.x
;
394 advance
.y
= metrics
->vertAdvance
;
395 FT_Vector_Transform( &advance
, &font_matrix
);
396 metrics
->vertAdvance
= advance
.y
+ font_offset
.y
;
398 if ( ( load_flags
& FT_LOAD_NO_SCALE
) == 0 )
400 /* scale the outline and the metrics */
402 FT_Outline
* cur
= decoder
.builder
.base
;
403 FT_Vector
* vec
= cur
->points
;
404 FT_Fixed x_scale
= glyph
->x_scale
;
405 FT_Fixed y_scale
= glyph
->y_scale
;
408 /* First of all, scale the points */
409 if ( !hinting
|| !decoder
.builder
.hints_funcs
)
410 for ( n
= cur
->n_points
; n
> 0; n
--, vec
++ )
412 vec
->x
= FT_MulFix( vec
->x
, x_scale
);
413 vec
->y
= FT_MulFix( vec
->y
, y_scale
);
416 /* Then scale the metrics */
417 metrics
->horiAdvance
= FT_MulFix( metrics
->horiAdvance
, x_scale
);
418 metrics
->vertAdvance
= FT_MulFix( metrics
->vertAdvance
, y_scale
);
421 /* compute the other metrics */
422 FT_Outline_Get_CBox( &cidglyph
->outline
, &cbox
);
424 metrics
->width
= cbox
.xMax
- cbox
.xMin
;
425 metrics
->height
= cbox
.yMax
- cbox
.yMin
;
427 metrics
->horiBearingX
= cbox
.xMin
;
428 metrics
->horiBearingY
= cbox
.yMax
;
430 if ( load_flags
& FT_LOAD_VERTICAL_LAYOUT
)
432 /* make up vertical ones */
433 ft_synthesize_vertical_metrics( metrics
,
434 metrics
->vertAdvance
);