1/****************************************************************************
2 *
3 * t1gload.c
4 *
5 * Type 1 Glyph Loader (body).
6 *
7 * Copyright (C) 1996-2023 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 "t1gload.h"
20#include <freetype/internal/ftcalc.h>
21#include <freetype/internal/ftdebug.h>
22#include <freetype/internal/ftstream.h>
23#include <freetype/ftoutln.h>
24#include <freetype/internal/psaux.h>
25#include <freetype/internal/cfftypes.h>
26#include <freetype/ftdriver.h>
27
28#include "t1errors.h"
29
30
31 /**************************************************************************
32 *
33 * The macro FT_COMPONENT is used in trace mode. It is an implicit
34 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
35 * messages during execution.
36 */
37#undef FT_COMPONENT
38#define FT_COMPONENT t1gload
39
40
41 static FT_Error
42 T1_Parse_Glyph_And_Get_Char_String( T1_Decoder decoder,
43 FT_UInt glyph_index,
44 FT_Data* char_string,
45 FT_Bool* force_scaling )
46 {
47 T1_Face face = (T1_Face)decoder->builder.face;
48 T1_Font type1 = &face->type1;
49 FT_Error error = FT_Err_Ok;
50
51 PSAux_Service psaux = (PSAux_Service)face->psaux;
52 const T1_Decoder_Funcs decoder_funcs = psaux->t1_decoder_funcs;
53 PS_Decoder psdecoder;
54
55#ifdef FT_CONFIG_OPTION_INCREMENTAL
56 FT_Incremental_InterfaceRec *inc =
57 face->root.internal->incremental_interface;
58#endif
59
60#ifdef T1_CONFIG_OPTION_OLD_ENGINE
61 PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( face );
62#endif
63
64
65 decoder->font_matrix = type1->font_matrix;
66 decoder->font_offset = type1->font_offset;
67
68#ifdef FT_CONFIG_OPTION_INCREMENTAL
69
70 /* For incremental fonts get the character data using the */
71 /* callback function. */
72 if ( inc )
73 error = inc->funcs->get_glyph_data( inc->object,
74 glyph_index, char_string );
75 else
76
77#endif /* FT_CONFIG_OPTION_INCREMENTAL */
78
79 /* For ordinary fonts get the character data stored in the face record. */
80 {
81 char_string->pointer = type1->charstrings[glyph_index];
82 char_string->length = type1->charstrings_len[glyph_index];
83 }
84
85 if ( !error )
86 {
87 /* choose which renderer to use */
88#ifdef T1_CONFIG_OPTION_OLD_ENGINE
89 if ( driver->hinting_engine == FT_HINTING_FREETYPE ||
90 decoder->builder.metrics_only )
91 error = decoder_funcs->parse_charstrings_old(
92 decoder,
93 (FT_Byte*)char_string->pointer,
94 (FT_UInt)char_string->length );
95#else
96 if ( decoder->builder.metrics_only )
97 error = decoder_funcs->parse_metrics(
98 decoder,
99 (FT_Byte*)char_string->pointer,
100 (FT_UInt)char_string->length );
101#endif
102 else
103 {
104 CFF_SubFontRec subfont;
105
106
107 psaux->ps_decoder_init( &psdecoder, decoder, TRUE );
108
109 psaux->t1_make_subfont( FT_FACE( face ),
110 &face->type1.private_dict, &subfont );
111 psdecoder.current_subfont = &subfont;
112
113 error = decoder_funcs->parse_charstrings(
114 &psdecoder,
115 (FT_Byte*)char_string->pointer,
116 (FT_ULong)char_string->length );
117
118 /* Adobe's engine uses 16.16 numbers everywhere; */
119 /* as a consequence, glyphs larger than 2000ppem get rejected */
120 if ( FT_ERR_EQ( error, Glyph_Too_Big ) )
121 {
122 /* this time, we retry unhinted and scale up the glyph later on */
123 /* (the engine uses and sets the hardcoded value 0x10000 / 64 = */
124 /* 0x400 for both `x_scale' and `y_scale' in this case) */
125 ((T1_GlyphSlot)decoder->builder.glyph)->hint = FALSE;
126
127 *force_scaling = TRUE;
128
129 error = decoder_funcs->parse_charstrings(
130 &psdecoder,
131 (FT_Byte*)char_string->pointer,
132 (FT_ULong)char_string->length );
133 }
134 }
135 }
136
137#ifdef FT_CONFIG_OPTION_INCREMENTAL
138
139 /* Incremental fonts can optionally override the metrics. */
140 if ( !error && inc && inc->funcs->get_glyph_metrics )
141 {
142 FT_Incremental_MetricsRec metrics;
143
144
145 metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x );
146 metrics.bearing_y = 0;
147 metrics.advance = FIXED_TO_INT( decoder->builder.advance.x );
148 metrics.advance_v = FIXED_TO_INT( decoder->builder.advance.y );
149
150 error = inc->funcs->get_glyph_metrics( inc->object,
151 glyph_index, FALSE, &metrics );
152
153 decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x );
154 decoder->builder.advance.x = INT_TO_FIXED( metrics.advance );
155 decoder->builder.advance.y = INT_TO_FIXED( metrics.advance_v );
156 }
157
158#endif /* FT_CONFIG_OPTION_INCREMENTAL */
159
160 return error;
161 }
162
163
164 FT_CALLBACK_DEF( FT_Error )
165 T1_Parse_Glyph( T1_Decoder decoder,
166 FT_UInt glyph_index )
167 {
168 FT_Data glyph_data;
169 FT_Bool force_scaling = FALSE;
170 FT_Error error = T1_Parse_Glyph_And_Get_Char_String(
171 decoder, glyph_index, &glyph_data,
172 &force_scaling );
173
174
175#ifdef FT_CONFIG_OPTION_INCREMENTAL
176
177 if ( !error )
178 {
179 T1_Face face = (T1_Face)decoder->builder.face;
180
181
182 if ( face->root.internal->incremental_interface )
183 face->root.internal->incremental_interface->funcs->free_glyph_data(
184 face->root.internal->incremental_interface->object,
185 &glyph_data );
186 }
187
188#endif /* FT_CONFIG_OPTION_INCREMENTAL */
189
190 return error;
191 }
192
193
194 /*************************************************************************/
195 /*************************************************************************/
196 /*************************************************************************/
197 /********** *********/
198 /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/
199 /********** *********/
200 /********** The following code is in charge of computing *********/
201 /********** the maximum advance width of the font. It *********/
202 /********** quickly processes each glyph charstring to *********/
203 /********** extract the value from either a `sbw' or `seac' *********/
204 /********** operator. *********/
205 /********** *********/
206 /*************************************************************************/
207 /*************************************************************************/
208 /*************************************************************************/
209
210
211 FT_LOCAL_DEF( FT_Error )
212 T1_Compute_Max_Advance( T1_Face face,
213 FT_Pos* max_advance )
214 {
215 FT_Error error;
216 T1_DecoderRec decoder;
217 FT_Int glyph_index;
218 T1_Font type1 = &face->type1;
219 PSAux_Service psaux = (PSAux_Service)face->psaux;
220
221
222 FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) );
223
224 *max_advance = 0;
225
226 /* initialize load decoder */
227 error = psaux->t1_decoder_funcs->init( &decoder,
228 (FT_Face)face,
229 0, /* size */
230 0, /* glyph slot */
231 (FT_Byte**)type1->glyph_names,
232 face->blend,
233 0,
234 FT_RENDER_MODE_NORMAL,
235 T1_Parse_Glyph );
236 if ( error )
237 return error;
238
239 decoder.builder.metrics_only = 1;
240 decoder.builder.load_points = 0;
241
242 decoder.num_subrs = type1->num_subrs;
243 decoder.subrs = type1->subrs;
244 decoder.subrs_len = type1->subrs_len;
245 decoder.subrs_hash = type1->subrs_hash;
246
247 decoder.buildchar = face->buildchar;
248 decoder.len_buildchar = face->len_buildchar;
249
250 *max_advance = 0;
251
252 FT_TRACE6(( "T1_Compute_Max_Advance:\n" ));
253
254 /* for each glyph, parse the glyph charstring and extract */
255 /* the advance width */
256 for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ )
257 {
258 /* now get load the unscaled outline */
259 (void)T1_Parse_Glyph( &decoder, (FT_UInt)glyph_index );
260 if ( glyph_index == 0 || decoder.builder.advance.x > *max_advance )
261 *max_advance = decoder.builder.advance.x;
262
263 /* ignore the error if one occurred - skip to next glyph */
264 }
265
266 FT_TRACE6(( "T1_Compute_Max_Advance: max advance: %f\n",
267 (double)*max_advance / 65536 ));
268
269 psaux->t1_decoder_funcs->done( &decoder );
270
271 return FT_Err_Ok;
272 }
273
274
275 FT_LOCAL_DEF( FT_Error )
276 T1_Get_Advances( FT_Face t1face, /* T1_Face */
277 FT_UInt first,
278 FT_UInt count,
279 FT_Int32 load_flags,
280 FT_Fixed* advances )
281 {
282 T1_Face face = (T1_Face)t1face;
283 T1_DecoderRec decoder;
284 T1_Font type1 = &face->type1;
285 PSAux_Service psaux = (PSAux_Service)face->psaux;
286 FT_UInt nn;
287 FT_Error error;
288
289
290 FT_TRACE5(( "T1_Get_Advances:\n" ));
291
292 if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
293 {
294 for ( nn = 0; nn < count; nn++ )
295 {
296 advances[nn] = 0;
297
298 FT_TRACE5(( " idx %d: advance height 0 font units\n",
299 first + nn ));
300 }
301
302 return FT_Err_Ok;
303 }
304
305 error = psaux->t1_decoder_funcs->init( &decoder,
306 (FT_Face)face,
307 0, /* size */
308 0, /* glyph slot */
309 (FT_Byte**)type1->glyph_names,
310 face->blend,
311 0,
312 FT_RENDER_MODE_NORMAL,
313 T1_Parse_Glyph );
314 if ( error )
315 return error;
316
317 decoder.builder.metrics_only = 1;
318 decoder.builder.load_points = 0;
319
320 decoder.num_subrs = type1->num_subrs;
321 decoder.subrs = type1->subrs;
322 decoder.subrs_len = type1->subrs_len;
323 decoder.subrs_hash = type1->subrs_hash;
324
325 decoder.buildchar = face->buildchar;
326 decoder.len_buildchar = face->len_buildchar;
327
328 for ( nn = 0; nn < count; nn++ )
329 {
330 error = T1_Parse_Glyph( &decoder, first + nn );
331 if ( !error )
332 advances[nn] = FIXED_TO_INT( decoder.builder.advance.x );
333 else
334 advances[nn] = 0;
335
336 FT_TRACE5(( " idx %d: advance width %ld font unit%s\n",
337 first + nn,
338 advances[nn],
339 advances[nn] == 1 ? "" : "s" ));
340 }
341
342 return FT_Err_Ok;
343 }
344
345
346 FT_LOCAL_DEF( FT_Error )
347 T1_Load_Glyph( FT_GlyphSlot t1glyph, /* T1_GlyphSlot */
348 FT_Size t1size, /* T1_Size */
349 FT_UInt glyph_index,
350 FT_Int32 load_flags )
351 {
352 T1_GlyphSlot glyph = (T1_GlyphSlot)t1glyph;
353 FT_Error error;
354 T1_DecoderRec decoder;
355 T1_Face face = (T1_Face)t1glyph->face;
356 FT_Bool hinting;
357 FT_Bool scaled;
358 FT_Bool force_scaling = FALSE;
359 T1_Font type1 = &face->type1;
360 PSAux_Service psaux = (PSAux_Service)face->psaux;
361 const T1_Decoder_Funcs decoder_funcs = psaux->t1_decoder_funcs;
362
363 FT_Matrix font_matrix;
364 FT_Vector font_offset;
365 FT_Data glyph_data;
366 FT_Bool must_finish_decoder = FALSE;
367#ifdef FT_CONFIG_OPTION_INCREMENTAL
368 FT_Bool glyph_data_loaded = 0;
369#endif
370
371
372#ifdef FT_CONFIG_OPTION_INCREMENTAL
373 if ( glyph_index >= (FT_UInt)face->root.num_glyphs &&
374 !face->root.internal->incremental_interface )
375#else
376 if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
377#endif /* FT_CONFIG_OPTION_INCREMENTAL */
378 {
379 error = FT_THROW( Invalid_Argument );
380 goto Exit;
381 }
382
383 FT_TRACE1(( "T1_Load_Glyph: glyph index %d\n", glyph_index ));
384
385 FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) );
386
387 if ( load_flags & FT_LOAD_NO_RECURSE )
388 load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
389
390 if ( t1size )
391 {
392 glyph->x_scale = t1size->metrics.x_scale;
393 glyph->y_scale = t1size->metrics.y_scale;
394 }
395 else
396 {
397 glyph->x_scale = 0x10000L;
398 glyph->y_scale = 0x10000L;
399 }
400
401 t1glyph->outline.n_points = 0;
402 t1glyph->outline.n_contours = 0;
403
404 hinting = FT_BOOL( !( load_flags & FT_LOAD_NO_SCALE ) &&
405 !( load_flags & FT_LOAD_NO_HINTING ) );
406 scaled = FT_BOOL( !( load_flags & FT_LOAD_NO_SCALE ) );
407
408 glyph->hint = hinting;
409 glyph->scaled = scaled;
410 t1glyph->format = FT_GLYPH_FORMAT_OUTLINE;
411
412 error = decoder_funcs->init( &decoder,
413 t1glyph->face,
414 t1size,
415 t1glyph,
416 (FT_Byte**)type1->glyph_names,
417 face->blend,
418 hinting,
419 FT_LOAD_TARGET_MODE( load_flags ),
420 T1_Parse_Glyph );
421 if ( error )
422 goto Exit;
423
424 must_finish_decoder = TRUE;
425
426 decoder.builder.no_recurse = FT_BOOL( load_flags & FT_LOAD_NO_RECURSE );
427
428 decoder.num_subrs = type1->num_subrs;
429 decoder.subrs = type1->subrs;
430 decoder.subrs_len = type1->subrs_len;
431 decoder.subrs_hash = type1->subrs_hash;
432
433 decoder.buildchar = face->buildchar;
434 decoder.len_buildchar = face->len_buildchar;
435
436 /* now load the unscaled outline */
437 error = T1_Parse_Glyph_And_Get_Char_String( &decoder, glyph_index,
438 &glyph_data,
439 &force_scaling );
440 if ( error )
441 goto Exit;
442#ifdef FT_CONFIG_OPTION_INCREMENTAL
443 glyph_data_loaded = 1;
444#endif
445
446 hinting = glyph->hint;
447 font_matrix = decoder.font_matrix;
448 font_offset = decoder.font_offset;
449
450 /* save new glyph tables */
451 decoder_funcs->done( &decoder );
452
453 must_finish_decoder = FALSE;
454
455 /* now, set the metrics -- this is rather simple, as */
456 /* the left side bearing is the xMin, and the top side */
457 /* bearing the yMax */
458 if ( !error )
459 {
460 t1glyph->outline.flags &= FT_OUTLINE_OWNER;
461 t1glyph->outline.flags |= FT_OUTLINE_REVERSE_FILL;
462
463 /* for composite glyphs, return only left side bearing and */
464 /* advance width */
465 if ( load_flags & FT_LOAD_NO_RECURSE )
466 {
467 FT_Slot_Internal internal = t1glyph->internal;
468
469
470 t1glyph->metrics.horiBearingX =
471 FIXED_TO_INT( decoder.builder.left_bearing.x );
472 t1glyph->metrics.horiAdvance =
473 FIXED_TO_INT( decoder.builder.advance.x );
474
475 internal->glyph_matrix = font_matrix;
476 internal->glyph_delta = font_offset;
477 internal->glyph_transformed = 1;
478 }
479 else
480 {
481 FT_BBox cbox;
482 FT_Glyph_Metrics* metrics = &t1glyph->metrics;
483
484
485 /* copy the _unscaled_ advance width */
486 metrics->horiAdvance =
487 FIXED_TO_INT( decoder.builder.advance.x );
488 t1glyph->linearHoriAdvance =
489 FIXED_TO_INT( decoder.builder.advance.x );
490 t1glyph->internal->glyph_transformed = 0;
491
492 if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
493 {
494 /* make up vertical ones */
495 metrics->vertAdvance = ( face->type1.font_bbox.yMax -
496 face->type1.font_bbox.yMin ) >> 16;
497 t1glyph->linearVertAdvance = metrics->vertAdvance;
498 }
499 else
500 {
501 metrics->vertAdvance =
502 FIXED_TO_INT( decoder.builder.advance.y );
503 t1glyph->linearVertAdvance =
504 FIXED_TO_INT( decoder.builder.advance.y );
505 }
506
507 t1glyph->format = FT_GLYPH_FORMAT_OUTLINE;
508
509 if ( t1size && t1size->metrics.y_ppem < 24 )
510 t1glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
511
512#if 1
513 /* apply the font matrix, if any */
514 if ( font_matrix.xx != 0x10000L || font_matrix.yy != 0x10000L ||
515 font_matrix.xy != 0 || font_matrix.yx != 0 )
516 {
517 FT_Outline_Transform( &t1glyph->outline, &font_matrix );
518
519 metrics->horiAdvance = FT_MulFix( metrics->horiAdvance,
520 font_matrix.xx );
521 metrics->vertAdvance = FT_MulFix( metrics->vertAdvance,
522 font_matrix.yy );
523 }
524
525 if ( font_offset.x || font_offset.y )
526 {
527 FT_Outline_Translate( &t1glyph->outline,
528 font_offset.x,
529 font_offset.y );
530
531 metrics->horiAdvance += font_offset.x;
532 metrics->vertAdvance += font_offset.y;
533 }
534#endif
535
536 if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 || force_scaling )
537 {
538 /* scale the outline and the metrics */
539 FT_Int n;
540 FT_Outline* cur = decoder.builder.base;
541 FT_Vector* vec = cur->points;
542 FT_Fixed x_scale = glyph->x_scale;
543 FT_Fixed y_scale = glyph->y_scale;
544
545
546 /* First of all, scale the points, if we are not hinting */
547 if ( !hinting || !decoder.builder.hints_funcs )
548 for ( n = cur->n_points; n > 0; n--, vec++ )
549 {
550 vec->x = FT_MulFix( vec->x, x_scale );
551 vec->y = FT_MulFix( vec->y, y_scale );
552 }
553
554 /* Then scale the metrics */
555 metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
556 metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );
557 }
558
559 /* compute the other metrics */
560 FT_Outline_Get_CBox( &t1glyph->outline, &cbox );
561
562 metrics->width = cbox.xMax - cbox.xMin;
563 metrics->height = cbox.yMax - cbox.yMin;
564
565 metrics->horiBearingX = cbox.xMin;
566 metrics->horiBearingY = cbox.yMax;
567
568 if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
569 {
570 /* make up vertical ones */
571 ft_synthesize_vertical_metrics( metrics,
572 metrics->vertAdvance );
573 }
574 }
575
576 /* Set control data to the glyph charstrings. Note that this is */
577 /* _not_ zero-terminated. */
578 t1glyph->control_data = (FT_Byte*)glyph_data.pointer;
579 t1glyph->control_len = glyph_data.length;
580 }
581
582
583 Exit:
584
585#ifdef FT_CONFIG_OPTION_INCREMENTAL
586 if ( glyph_data_loaded && face->root.internal->incremental_interface )
587 {
588 face->root.internal->incremental_interface->funcs->free_glyph_data(
589 face->root.internal->incremental_interface->object,
590 &glyph_data );
591
592 /* Set the control data to null - it is no longer available if */
593 /* loaded incrementally. */
594 t1glyph->control_data = NULL;
595 t1glyph->control_len = 0;
596 }
597#endif
598
599 if ( must_finish_decoder )
600 decoder_funcs->done( &decoder );
601
602 return error;
603 }
604
605
606/* END */
607