1 /***************************************************************************/ |
|
2 /* */ |
|
3 /* t1gload.c */ |
|
4 /* */ |
|
5 /* Type 1 Glyph Loader (body). */ |
|
6 /* */ |
|
7 /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010 by */ |
|
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
|
9 /* */ |
|
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. */ |
|
15 /* */ |
|
16 /***************************************************************************/ |
|
17 |
|
18 |
|
19 #include <ft2build.h> |
|
20 #include "t1gload.h" |
|
21 #include FT_INTERNAL_CALC_H |
|
22 #include FT_INTERNAL_DEBUG_H |
|
23 #include FT_INTERNAL_STREAM_H |
|
24 #include FT_OUTLINE_H |
|
25 #include FT_INTERNAL_POSTSCRIPT_AUX_H |
|
26 |
|
27 #include "t1errors.h" |
|
28 |
|
29 |
|
30 /*************************************************************************/ |
|
31 /* */ |
|
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. */ |
|
35 /* */ |
|
36 #undef FT_COMPONENT |
|
37 #define FT_COMPONENT trace_t1gload |
|
38 |
|
39 |
|
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 /*************************************************************************/ |
|
55 |
|
56 |
|
57 FT_LOCAL_DEF( FT_Error ) |
|
58 T1_Parse_Glyph_And_Get_Char_String( T1_Decoder decoder, |
|
59 FT_UInt glyph_index, |
|
60 FT_Data* char_string ) |
|
61 { |
|
62 T1_Face face = (T1_Face)decoder->builder.face; |
|
63 T1_Font type1 = &face->type1; |
|
64 FT_Error error = T1_Err_Ok; |
|
65 |
|
66 #ifdef FT_CONFIG_OPTION_INCREMENTAL |
|
67 FT_Incremental_InterfaceRec *inc = |
|
68 face->root.internal->incremental_interface; |
|
69 #endif |
|
70 |
|
71 |
|
72 decoder->font_matrix = type1->font_matrix; |
|
73 decoder->font_offset = type1->font_offset; |
|
74 |
|
75 #ifdef FT_CONFIG_OPTION_INCREMENTAL |
|
76 |
|
77 /* For incremental fonts get the character data using the */ |
|
78 /* callback function. */ |
|
79 if ( inc ) |
|
80 error = inc->funcs->get_glyph_data( inc->object, |
|
81 glyph_index, char_string ); |
|
82 else |
|
83 |
|
84 #endif /* FT_CONFIG_OPTION_INCREMENTAL */ |
|
85 |
|
86 /* For ordinary fonts get the character data stored in the face record. */ |
|
87 { |
|
88 char_string->pointer = type1->charstrings[glyph_index]; |
|
89 char_string->length = (FT_Int)type1->charstrings_len[glyph_index]; |
|
90 } |
|
91 |
|
92 if ( !error ) |
|
93 error = decoder->funcs.parse_charstrings( |
|
94 decoder, (FT_Byte*)char_string->pointer, |
|
95 char_string->length ); |
|
96 |
|
97 #ifdef FT_CONFIG_OPTION_INCREMENTAL |
|
98 |
|
99 /* Incremental fonts can optionally override the metrics. */ |
|
100 if ( !error && inc && inc->funcs->get_glyph_metrics ) |
|
101 { |
|
102 FT_Incremental_MetricsRec metrics; |
|
103 |
|
104 |
|
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 ); |
|
109 |
|
110 error = inc->funcs->get_glyph_metrics( inc->object, |
|
111 glyph_index, FALSE, &metrics ); |
|
112 |
|
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 ); |
|
116 } |
|
117 |
|
118 #endif /* FT_CONFIG_OPTION_INCREMENTAL */ |
|
119 |
|
120 return error; |
|
121 } |
|
122 |
|
123 |
|
124 FT_CALLBACK_DEF( FT_Error ) |
|
125 T1_Parse_Glyph( T1_Decoder decoder, |
|
126 FT_UInt glyph_index ) |
|
127 { |
|
128 FT_Data glyph_data; |
|
129 FT_Error error = T1_Parse_Glyph_And_Get_Char_String( |
|
130 decoder, glyph_index, &glyph_data ); |
|
131 |
|
132 |
|
133 #ifdef FT_CONFIG_OPTION_INCREMENTAL |
|
134 |
|
135 if ( !error ) |
|
136 { |
|
137 T1_Face face = (T1_Face)decoder->builder.face; |
|
138 |
|
139 |
|
140 if ( face->root.internal->incremental_interface ) |
|
141 face->root.internal->incremental_interface->funcs->free_glyph_data( |
|
142 face->root.internal->incremental_interface->object, |
|
143 &glyph_data ); |
|
144 } |
|
145 |
|
146 #endif /* FT_CONFIG_OPTION_INCREMENTAL */ |
|
147 |
|
148 return error; |
|
149 } |
|
150 |
|
151 |
|
152 FT_LOCAL_DEF( FT_Error ) |
|
153 T1_Compute_Max_Advance( T1_Face face, |
|
154 FT_Pos* max_advance ) |
|
155 { |
|
156 FT_Error error; |
|
157 T1_DecoderRec decoder; |
|
158 FT_Int glyph_index; |
|
159 T1_Font type1 = &face->type1; |
|
160 PSAux_Service psaux = (PSAux_Service)face->psaux; |
|
161 |
|
162 |
|
163 FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); |
|
164 |
|
165 *max_advance = 0; |
|
166 |
|
167 /* initialize load decoder */ |
|
168 error = psaux->t1_decoder_funcs->init( &decoder, |
|
169 (FT_Face)face, |
|
170 0, /* size */ |
|
171 0, /* glyph slot */ |
|
172 (FT_Byte**)type1->glyph_names, |
|
173 face->blend, |
|
174 0, |
|
175 FT_RENDER_MODE_NORMAL, |
|
176 T1_Parse_Glyph ); |
|
177 if ( error ) |
|
178 return error; |
|
179 |
|
180 decoder.builder.metrics_only = 1; |
|
181 decoder.builder.load_points = 0; |
|
182 |
|
183 decoder.num_subrs = type1->num_subrs; |
|
184 decoder.subrs = type1->subrs; |
|
185 decoder.subrs_len = type1->subrs_len; |
|
186 |
|
187 decoder.buildchar = face->buildchar; |
|
188 decoder.len_buildchar = face->len_buildchar; |
|
189 |
|
190 *max_advance = 0; |
|
191 |
|
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++ ) |
|
195 { |
|
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; |
|
200 |
|
201 /* ignore the error if one occurred - skip to next glyph */ |
|
202 } |
|
203 |
|
204 psaux->t1_decoder_funcs->done( &decoder ); |
|
205 |
|
206 return T1_Err_Ok; |
|
207 } |
|
208 |
|
209 |
|
210 FT_LOCAL_DEF( FT_Error ) |
|
211 T1_Get_Advances( T1_Face face, |
|
212 FT_UInt first, |
|
213 FT_UInt count, |
|
214 FT_ULong load_flags, |
|
215 FT_Fixed* advances ) |
|
216 { |
|
217 T1_DecoderRec decoder; |
|
218 T1_Font type1 = &face->type1; |
|
219 PSAux_Service psaux = (PSAux_Service)face->psaux; |
|
220 FT_UInt nn; |
|
221 FT_Error error; |
|
222 |
|
223 |
|
224 if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) |
|
225 { |
|
226 for ( nn = 0; nn < count; nn++ ) |
|
227 advances[nn] = 0; |
|
228 |
|
229 return T1_Err_Ok; |
|
230 } |
|
231 |
|
232 error = psaux->t1_decoder_funcs->init( &decoder, |
|
233 (FT_Face)face, |
|
234 0, /* size */ |
|
235 0, /* glyph slot */ |
|
236 (FT_Byte**)type1->glyph_names, |
|
237 face->blend, |
|
238 0, |
|
239 FT_RENDER_MODE_NORMAL, |
|
240 T1_Parse_Glyph ); |
|
241 if ( error ) |
|
242 return error; |
|
243 |
|
244 decoder.builder.metrics_only = 1; |
|
245 decoder.builder.load_points = 0; |
|
246 |
|
247 decoder.num_subrs = type1->num_subrs; |
|
248 decoder.subrs = type1->subrs; |
|
249 decoder.subrs_len = type1->subrs_len; |
|
250 |
|
251 decoder.buildchar = face->buildchar; |
|
252 decoder.len_buildchar = face->len_buildchar; |
|
253 |
|
254 for ( nn = 0; nn < count; nn++ ) |
|
255 { |
|
256 error = T1_Parse_Glyph( &decoder, first + nn ); |
|
257 if ( !error ) |
|
258 advances[nn] = FIXED_TO_INT( decoder.builder.advance.x ); |
|
259 else |
|
260 advances[nn] = 0; |
|
261 } |
|
262 |
|
263 return T1_Err_Ok; |
|
264 } |
|
265 |
|
266 |
|
267 FT_LOCAL_DEF( FT_Error ) |
|
268 T1_Load_Glyph( T1_GlyphSlot glyph, |
|
269 T1_Size size, |
|
270 FT_UInt glyph_index, |
|
271 FT_Int32 load_flags ) |
|
272 { |
|
273 FT_Error error; |
|
274 T1_DecoderRec decoder; |
|
275 T1_Face face = (T1_Face)glyph->root.face; |
|
276 FT_Bool hinting; |
|
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; |
|
280 |
|
281 FT_Matrix font_matrix; |
|
282 FT_Vector font_offset; |
|
283 FT_Data glyph_data; |
|
284 FT_Bool must_finish_decoder = FALSE; |
|
285 #ifdef FT_CONFIG_OPTION_INCREMENTAL |
|
286 FT_Bool glyph_data_loaded = 0; |
|
287 #endif |
|
288 |
|
289 |
|
290 #ifdef FT_CONFIG_OPTION_INCREMENTAL |
|
291 if ( glyph_index >= (FT_UInt)face->root.num_glyphs && |
|
292 !face->root.internal->incremental_interface ) |
|
293 #else |
|
294 if ( glyph_index >= (FT_UInt)face->root.num_glyphs ) |
|
295 #endif /* FT_CONFIG_OPTION_INCREMENTAL */ |
|
296 { |
|
297 error = T1_Err_Invalid_Argument; |
|
298 goto Exit; |
|
299 } |
|
300 |
|
301 FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) ); |
|
302 |
|
303 if ( load_flags & FT_LOAD_NO_RECURSE ) |
|
304 load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; |
|
305 |
|
306 if ( size ) |
|
307 { |
|
308 glyph->x_scale = size->root.metrics.x_scale; |
|
309 glyph->y_scale = size->root.metrics.y_scale; |
|
310 } |
|
311 else |
|
312 { |
|
313 glyph->x_scale = 0x10000L; |
|
314 glyph->y_scale = 0x10000L; |
|
315 } |
|
316 |
|
317 glyph->root.outline.n_points = 0; |
|
318 glyph->root.outline.n_contours = 0; |
|
319 |
|
320 hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 && |
|
321 ( load_flags & FT_LOAD_NO_HINTING ) == 0 ); |
|
322 |
|
323 glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; |
|
324 |
|
325 error = decoder_funcs->init( &decoder, |
|
326 (FT_Face)face, |
|
327 (FT_Size)size, |
|
328 (FT_GlyphSlot)glyph, |
|
329 (FT_Byte**)type1->glyph_names, |
|
330 face->blend, |
|
331 FT_BOOL( hinting ), |
|
332 FT_LOAD_TARGET_MODE( load_flags ), |
|
333 T1_Parse_Glyph ); |
|
334 if ( error ) |
|
335 goto Exit; |
|
336 |
|
337 must_finish_decoder = TRUE; |
|
338 |
|
339 decoder.builder.no_recurse = FT_BOOL( |
|
340 ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ); |
|
341 |
|
342 decoder.num_subrs = type1->num_subrs; |
|
343 decoder.subrs = type1->subrs; |
|
344 decoder.subrs_len = type1->subrs_len; |
|
345 |
|
346 decoder.buildchar = face->buildchar; |
|
347 decoder.len_buildchar = face->len_buildchar; |
|
348 |
|
349 /* now load the unscaled outline */ |
|
350 error = T1_Parse_Glyph_And_Get_Char_String( &decoder, glyph_index, |
|
351 &glyph_data ); |
|
352 if ( error ) |
|
353 goto Exit; |
|
354 #ifdef FT_CONFIG_OPTION_INCREMENTAL |
|
355 glyph_data_loaded = 1; |
|
356 #endif |
|
357 |
|
358 font_matrix = decoder.font_matrix; |
|
359 font_offset = decoder.font_offset; |
|
360 |
|
361 /* save new glyph tables */ |
|
362 decoder_funcs->done( &decoder ); |
|
363 |
|
364 must_finish_decoder = FALSE; |
|
365 |
|
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 */ |
|
369 if ( !error ) |
|
370 { |
|
371 glyph->root.outline.flags &= FT_OUTLINE_OWNER; |
|
372 glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL; |
|
373 |
|
374 /* for composite glyphs, return only left side bearing and */ |
|
375 /* advance width */ |
|
376 if ( load_flags & FT_LOAD_NO_RECURSE ) |
|
377 { |
|
378 FT_Slot_Internal internal = glyph->root.internal; |
|
379 |
|
380 |
|
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 ); |
|
385 |
|
386 internal->glyph_matrix = font_matrix; |
|
387 internal->glyph_delta = font_offset; |
|
388 internal->glyph_transformed = 1; |
|
389 } |
|
390 else |
|
391 { |
|
392 FT_BBox cbox; |
|
393 FT_Glyph_Metrics* metrics = &glyph->root.metrics; |
|
394 FT_Vector advance; |
|
395 |
|
396 |
|
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; |
|
403 |
|
404 if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) |
|
405 { |
|
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; |
|
410 } |
|
411 else |
|
412 { |
|
413 metrics->vertAdvance = |
|
414 FIXED_TO_INT( decoder.builder.advance.y ); |
|
415 glyph->root.linearVertAdvance = |
|
416 FIXED_TO_INT( decoder.builder.advance.y ); |
|
417 } |
|
418 |
|
419 glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; |
|
420 |
|
421 if ( size && size->root.metrics.y_ppem < 24 ) |
|
422 glyph->root.outline.flags |= FT_OUTLINE_HIGH_PRECISION; |
|
423 |
|
424 #if 1 |
|
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 ); |
|
429 |
|
430 if ( font_offset.x || font_offset.y ) |
|
431 FT_Outline_Translate( &glyph->root.outline, |
|
432 font_offset.x, |
|
433 font_offset.y ); |
|
434 |
|
435 advance.x = metrics->horiAdvance; |
|
436 advance.y = 0; |
|
437 FT_Vector_Transform( &advance, &font_matrix ); |
|
438 metrics->horiAdvance = advance.x + font_offset.x; |
|
439 advance.x = 0; |
|
440 advance.y = metrics->vertAdvance; |
|
441 FT_Vector_Transform( &advance, &font_matrix ); |
|
442 metrics->vertAdvance = advance.y + font_offset.y; |
|
443 #endif |
|
444 |
|
445 if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) |
|
446 { |
|
447 /* scale the outline and the metrics */ |
|
448 FT_Int n; |
|
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; |
|
453 |
|
454 |
|
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++ ) |
|
458 { |
|
459 vec->x = FT_MulFix( vec->x, x_scale ); |
|
460 vec->y = FT_MulFix( vec->y, y_scale ); |
|
461 } |
|
462 |
|
463 /* Then scale the metrics */ |
|
464 metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); |
|
465 metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); |
|
466 } |
|
467 |
|
468 /* compute the other metrics */ |
|
469 FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); |
|
470 |
|
471 metrics->width = cbox.xMax - cbox.xMin; |
|
472 metrics->height = cbox.yMax - cbox.yMin; |
|
473 |
|
474 metrics->horiBearingX = cbox.xMin; |
|
475 metrics->horiBearingY = cbox.yMax; |
|
476 |
|
477 if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) |
|
478 { |
|
479 /* make up vertical ones */ |
|
480 ft_synthesize_vertical_metrics( metrics, |
|
481 metrics->vertAdvance ); |
|
482 } |
|
483 } |
|
484 |
|
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; |
|
489 } |
|
490 |
|
491 |
|
492 Exit: |
|
493 |
|
494 #ifdef FT_CONFIG_OPTION_INCREMENTAL |
|
495 if ( glyph_data_loaded && face->root.internal->incremental_interface ) |
|
496 { |
|
497 face->root.internal->incremental_interface->funcs->free_glyph_data( |
|
498 face->root.internal->incremental_interface->object, |
|
499 &glyph_data ); |
|
500 |
|
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; |
|
505 } |
|
506 #endif |
|
507 |
|
508 if ( must_finish_decoder ) |
|
509 decoder_funcs->done( &decoder ); |
|
510 |
|
511 return error; |
|
512 } |
|
513 |
|
514 |
|
515 /* END */ |
|