1 /****************************************************************************
5 * Objects manager (body).
7 * Copyright (C) 1996-2020 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.
19 #include <freetype/internal/ftdebug.h>
20 #include <freetype/internal/ftstream.h>
21 #include <freetype/tttags.h>
22 #include <freetype/internal/sfnt.h>
23 #include <freetype/ftdriver.h>
30 #ifdef TT_USE_BYTECODE_INTERPRETER
34 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
38 /**************************************************************************
40 * The macro FT_COMPONENT is used in trace mode. It is an implicit
41 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
42 * messages during execution.
45 #define FT_COMPONENT ttobjs
48 #ifdef TT_USE_BYTECODE_INTERPRETER
50 /**************************************************************************
52 * GLYPH ZONE FUNCTIONS
57 /**************************************************************************
63 * Deallocate a glyph zone.
67 * A pointer to the target glyph zone.
70 tt_glyphzone_done( TT_GlyphZone zone
)
72 FT_Memory memory
= zone
->memory
;
77 FT_FREE( zone
->contours
);
78 FT_FREE( zone
->tags
);
81 FT_FREE( zone
->orus
);
83 zone
->max_points
= zone
->n_points
= 0;
84 zone
->max_contours
= zone
->n_contours
= 0;
90 /**************************************************************************
96 * Allocate a new glyph zone.
100 * A handle to the current memory object.
103 * The capacity of glyph zone in points.
106 * The capacity of glyph zone in contours.
110 * A pointer to the target glyph zone record.
113 * FreeType error code. 0 means success.
115 FT_LOCAL_DEF( FT_Error
)
116 tt_glyphzone_new( FT_Memory memory
,
118 FT_Short maxContours
,
125 zone
->memory
= memory
;
127 if ( FT_NEW_ARRAY( zone
->org
, maxPoints
) ||
128 FT_NEW_ARRAY( zone
->cur
, maxPoints
) ||
129 FT_NEW_ARRAY( zone
->orus
, maxPoints
) ||
130 FT_NEW_ARRAY( zone
->tags
, maxPoints
) ||
131 FT_NEW_ARRAY( zone
->contours
, maxContours
) )
133 tt_glyphzone_done( zone
);
137 zone
->max_points
= maxPoints
;
138 zone
->max_contours
= maxContours
;
143 #endif /* TT_USE_BYTECODE_INTERPRETER */
146 /* Compare the face with a list of well-known `tricky' fonts. */
147 /* This list shall be expanded as we find more of them. */
150 tt_check_trickyness_family( const FT_String
* name
)
153 #define TRICK_NAMES_MAX_CHARACTERS 19
154 #define TRICK_NAMES_COUNT 26
156 static const char trick_names
[TRICK_NAMES_COUNT
]
157 [TRICK_NAMES_MAX_CHARACTERS
+ 1] =
160 PostScript names are given in brackets if they differ from the
161 family name. The version numbers, together with the copyright or
162 release year data, are taken from fonts available to the
165 Note that later versions of the fonts might be no longer tricky;
166 for example, `MingLiU' version 7.00 (file `mingliu.ttc' from
167 Windows 7) is an ordinary TTC with non-tricky subfonts.
170 "cpop", /* dftt-p7.ttf; version 1.00, 1992 [DLJGyShoMedium] */
171 "DFGirl-W6-WIN-BF", /* dftt-h6.ttf; version 1.00, 1993 */
172 "DFGothic-EB", /* DynaLab Inc. 1992-1995 */
173 "DFGyoSho-Lt", /* DynaLab Inc. 1992-1995 */
174 "DFHei-Md-HK-BF", /* maybe DynaLab Inc. */
175 "DFHSGothic-W5", /* DynaLab Inc. 1992-1995 */
176 "DFHSMincho-W3", /* DynaLab Inc. 1992-1995 */
177 "DFHSMincho-W7", /* DynaLab Inc. 1992-1995 */
178 "DFKaiSho-SB", /* dfkaisb.ttf */
180 "DFKaiShu-Md-HK-BF", /* maybe DynaLab Inc. */
181 "DFKai-SB", /* kaiu.ttf; version 3.00, 1998 [DFKaiShu-SB-Estd-BF] */
182 "DFMing-Bd-HK-BF", /* maybe DynaLab Inc. */
183 "DLC", /* dftt-m7.ttf; version 1.00, 1993 [DLCMingBold] */
184 /* dftt-f5.ttf; version 1.00, 1993 [DLCFongSung] */
185 "DLCHayMedium", /* dftt-b5.ttf; version 1.00, 1993 */
186 "DLCHayBold", /* dftt-b7.ttf; version 1.00, 1993 */
187 "DLCKaiMedium", /* dftt-k5.ttf; version 1.00, 1992 */
188 "DLCLiShu", /* dftt-l5.ttf; version 1.00, 1992 */
189 "DLCRoundBold", /* dftt-r7.ttf; version 1.00, 1993 */
190 "HuaTianKaiTi?", /* htkt2.ttf */
191 "HuaTianSongTi?", /* htst3.ttf */
192 "Ming(for ISO10646)", /* hkscsiic.ttf; version 0.12, 2007 [Ming] */
193 /* iicore.ttf; version 0.07, 2007 [Ming] */
194 "MingLiU", /* mingliu.ttf */
195 /* mingliu.ttc; version 3.21, 2001 */
196 "MingMedium", /* dftt-m5.ttf; version 1.00, 1993 [DLCMingMedium] */
197 "PMingLiU", /* mingliu.ttc; version 3.21, 2001 */
198 "MingLi43", /* mingli.ttf; version 1.00, 1992 */
204 for ( nn
= 0; nn
< TRICK_NAMES_COUNT
; nn
++ )
205 if ( ft_strstr( name
, trick_names
[nn
] ) )
212 /* XXX: This function should be in the `sfnt' module. */
214 /* Some PDF generators clear the checksums in the TrueType header table. */
215 /* For example, Quartz ContextPDF clears all entries, or Bullzip PDF */
216 /* Printer clears the entries for subsetted subtables. We thus have to */
217 /* recalculate the checksums where necessary. */
220 tt_synth_sfnt_checksum( FT_Stream stream
,
224 FT_UInt32 checksum
= 0;
228 if ( FT_FRAME_ENTER( length
) )
231 for ( ; length
> 3; length
-= 4 )
232 checksum
+= (FT_UInt32
)FT_GET_ULONG();
234 for ( i
= 3; length
> 0; length
--, i
-- )
235 checksum
+= (FT_UInt32
)FT_GET_BYTE() << ( i
* 8 );
243 /* XXX: This function should be in the `sfnt' module. */
246 tt_get_sfnt_checksum( TT_Face face
,
249 #if 0 /* if we believe the written value, use following part. */
250 if ( face
->dir_tables
[i
].CheckSum
)
251 return face
->dir_tables
[i
].CheckSum
;
254 if ( !face
->goto_table
)
257 if ( face
->goto_table( face
,
258 face
->dir_tables
[i
].Tag
,
263 return (FT_ULong
)tt_synth_sfnt_checksum( face
->root
.stream
,
264 face
->dir_tables
[i
].Length
);
268 typedef struct tt_sfnt_id_rec_
277 tt_check_trickyness_sfnt_ids( TT_Face face
)
279 #define TRICK_SFNT_IDS_PER_FACE 3
280 #define TRICK_SFNT_IDS_NUM_FACES 29
282 static const tt_sfnt_id_rec sfnt_id
[TRICK_SFNT_IDS_NUM_FACES
]
283 [TRICK_SFNT_IDS_PER_FACE
] = {
285 #define TRICK_SFNT_ID_cvt 0
286 #define TRICK_SFNT_ID_fpgm 1
287 #define TRICK_SFNT_ID_prep 2
290 { 0x05BCF058UL
, 0x000002E4UL
}, /* cvt */
291 { 0x28233BF1UL
, 0x000087C4UL
}, /* fpgm */
292 { 0xA344A1EAUL
, 0x000001E1UL
} /* prep */
294 { /* MingLiU 1996- */
295 { 0x05BCF058UL
, 0x000002E4UL
}, /* cvt */
296 { 0x28233BF1UL
, 0x000087C4UL
}, /* fpgm */
297 { 0xA344A1EBUL
, 0x000001E1UL
} /* prep */
300 { 0x12C3EBB2UL
, 0x00000350UL
}, /* cvt */
301 { 0xB680EE64UL
, 0x000087A7UL
}, /* fpgm */
302 { 0xCE939563UL
, 0x00000758UL
} /* prep */
305 { 0x11E5EAD4UL
, 0x00000350UL
}, /* cvt */
306 { 0xCE5956E9UL
, 0x0000BC85UL
}, /* fpgm */
307 { 0x8272F416UL
, 0x00000045UL
} /* prep */
309 { /* DFHei-Md-HK-BF */
310 { 0x1257EB46UL
, 0x00000350UL
}, /* cvt */
311 { 0xF699D160UL
, 0x0000715FUL
}, /* fpgm */
312 { 0xD222F568UL
, 0x000003BCUL
} /* prep */
314 { /* DFHSGothic-W5 */
315 { 0x1262EB4EUL
, 0x00000350UL
}, /* cvt */
316 { 0xE86A5D64UL
, 0x00007940UL
}, /* fpgm */
317 { 0x7850F729UL
, 0x000005FFUL
} /* prep */
319 { /* DFHSMincho-W3 */
320 { 0x122DEB0AUL
, 0x00000350UL
}, /* cvt */
321 { 0x3D16328AUL
, 0x0000859BUL
}, /* fpgm */
322 { 0xA93FC33BUL
, 0x000002CBUL
} /* prep */
324 { /* DFHSMincho-W7 */
325 { 0x125FEB26UL
, 0x00000350UL
}, /* cvt */
326 { 0xA5ACC982UL
, 0x00007EE1UL
}, /* fpgm */
327 { 0x90999196UL
, 0x0000041FUL
} /* prep */
330 { 0x11E5EAD4UL
, 0x00000350UL
}, /* cvt */
331 { 0x5A30CA3BUL
, 0x00009063UL
}, /* fpgm */
332 { 0x13A42602UL
, 0x0000007EUL
} /* prep */
334 { /* DFKaiShu, variant */
335 { 0x11E5EAD4UL
, 0x00000350UL
}, /* cvt */
336 { 0xA6E78C01UL
, 0x00008998UL
}, /* fpgm */
337 { 0x13A42602UL
, 0x0000007EUL
} /* prep */
339 { /* DFKaiShu-Md-HK-BF */
340 { 0x11E5EAD4UL
, 0x00000360UL
}, /* cvt */
341 { 0x9DB282B2UL
, 0x0000C06EUL
}, /* fpgm */
342 { 0x53E6D7CAUL
, 0x00000082UL
} /* prep */
344 { /* DFMing-Bd-HK-BF */
345 { 0x1243EB18UL
, 0x00000350UL
}, /* cvt */
346 { 0xBA0A8C30UL
, 0x000074ADUL
}, /* fpgm */
347 { 0xF3D83409UL
, 0x0000037BUL
} /* prep */
350 { 0x07DCF546UL
, 0x00000308UL
}, /* cvt */
351 { 0x40FE7C90UL
, 0x00008E2AUL
}, /* fpgm */
352 { 0x608174B5UL
, 0x0000007AUL
} /* prep */
355 { 0xEB891238UL
, 0x00000308UL
}, /* cvt */
356 { 0xD2E4DCD4UL
, 0x0000676FUL
}, /* fpgm */
357 { 0x8EA5F293UL
, 0x000003B8UL
} /* prep */
360 { 0xFFFBFFFCUL
, 0x00000008UL
}, /* cvt */
361 { 0x9C9E48B8UL
, 0x0000BEA2UL
}, /* fpgm */
362 { 0x70020112UL
, 0x00000008UL
} /* prep */
364 { /* HuaTianSongTi */
365 { 0xFFFBFFFCUL
, 0x00000008UL
}, /* cvt */
366 { 0x0A5A0483UL
, 0x00017C39UL
}, /* fpgm */
367 { 0x70020112UL
, 0x00000008UL
} /* prep */
369 { /* NEC fadpop7.ttf */
370 { 0x00000000UL
, 0x00000000UL
}, /* cvt */
371 { 0x40C92555UL
, 0x000000E5UL
}, /* fpgm */
372 { 0xA39B58E3UL
, 0x0000117CUL
} /* prep */
374 { /* NEC fadrei5.ttf */
375 { 0x00000000UL
, 0x00000000UL
}, /* cvt */
376 { 0x33C41652UL
, 0x000000E5UL
}, /* fpgm */
377 { 0x26D6C52AUL
, 0x00000F6AUL
} /* prep */
379 { /* NEC fangot7.ttf */
380 { 0x00000000UL
, 0x00000000UL
}, /* cvt */
381 { 0x6DB1651DUL
, 0x0000019DUL
}, /* fpgm */
382 { 0x6C6E4B03UL
, 0x00002492UL
} /* prep */
384 { /* NEC fangyo5.ttf */
385 { 0x00000000UL
, 0x00000000UL
}, /* cvt */
386 { 0x40C92555UL
, 0x000000E5UL
}, /* fpgm */
387 { 0xDE51FAD0UL
, 0x0000117CUL
} /* prep */
389 { /* NEC fankyo5.ttf */
390 { 0x00000000UL
, 0x00000000UL
}, /* cvt */
391 { 0x85E47664UL
, 0x000000E5UL
}, /* fpgm */
392 { 0xA6C62831UL
, 0x00001CAAUL
} /* prep */
394 { /* NEC fanrgo5.ttf */
395 { 0x00000000UL
, 0x00000000UL
}, /* cvt */
396 { 0x2D891CFDUL
, 0x0000019DUL
}, /* fpgm */
397 { 0xA0604633UL
, 0x00001DE8UL
} /* prep */
399 { /* NEC fangot5.ttc */
400 { 0x00000000UL
, 0x00000000UL
}, /* cvt */
401 { 0x40AA774CUL
, 0x000001CBUL
}, /* fpgm */
402 { 0x9B5CAA96UL
, 0x00001F9AUL
} /* prep */
404 { /* NEC fanmin3.ttc */
405 { 0x00000000UL
, 0x00000000UL
}, /* cvt */
406 { 0x0D3DE9CBUL
, 0x00000141UL
}, /* fpgm */
407 { 0xD4127766UL
, 0x00002280UL
} /* prep */
409 { /* NEC FA-Gothic, 1996 */
410 { 0x00000000UL
, 0x00000000UL
}, /* cvt */
411 { 0x4A692698UL
, 0x000001F0UL
}, /* fpgm */
412 { 0x340D4346UL
, 0x00001FCAUL
} /* prep */
414 { /* NEC FA-Minchou, 1996 */
415 { 0x00000000UL
, 0x00000000UL
}, /* cvt */
416 { 0xCD34C604UL
, 0x00000166UL
}, /* fpgm */
417 { 0x6CF31046UL
, 0x000022B0UL
} /* prep */
419 { /* NEC FA-RoundGothicB, 1996 */
420 { 0x00000000UL
, 0x00000000UL
}, /* cvt */
421 { 0x5DA75315UL
, 0x0000019DUL
}, /* fpgm */
422 { 0x40745A5FUL
, 0x000022E0UL
} /* prep */
424 { /* NEC FA-RoundGothicM, 1996 */
425 { 0x00000000UL
, 0x00000000UL
}, /* cvt */
426 { 0xF055FC48UL
, 0x000001C2UL
}, /* fpgm */
427 { 0x3900DED3UL
, 0x00001E18UL
} /* prep */
429 { /* MINGLI.TTF, 1992 */
430 { 0x00170003UL
, 0x00000060UL
}, /* cvt */
431 { 0xDBB4306EUL
, 0x000058AAUL
}, /* fpgm */
432 { 0xD643482AUL
, 0x00000035UL
} /* prep */
437 int num_matched_ids
[TRICK_SFNT_IDS_NUM_FACES
];
438 FT_Bool has_cvt
, has_fpgm
, has_prep
;
443 FT_MEM_SET( num_matched_ids
, 0,
444 sizeof ( int ) * TRICK_SFNT_IDS_NUM_FACES
);
449 for ( i
= 0; i
< face
->num_tables
; i
++ )
453 switch( face
->dir_tables
[i
].Tag
)
456 k
= TRICK_SFNT_ID_cvt
;
461 k
= TRICK_SFNT_ID_fpgm
;
466 k
= TRICK_SFNT_ID_prep
;
474 for ( j
= 0; j
< TRICK_SFNT_IDS_NUM_FACES
; j
++ )
475 if ( face
->dir_tables
[i
].Length
== sfnt_id
[j
][k
].Length
)
478 checksum
= tt_get_sfnt_checksum( face
, i
);
480 if ( sfnt_id
[j
][k
].CheckSum
== checksum
)
481 num_matched_ids
[j
]++;
483 if ( num_matched_ids
[j
] == TRICK_SFNT_IDS_PER_FACE
)
488 for ( j
= 0; j
< TRICK_SFNT_IDS_NUM_FACES
; j
++ )
490 if ( !has_cvt
&& !sfnt_id
[j
][TRICK_SFNT_ID_cvt
].Length
)
491 num_matched_ids
[j
]++;
492 if ( !has_fpgm
&& !sfnt_id
[j
][TRICK_SFNT_ID_fpgm
].Length
)
493 num_matched_ids
[j
]++;
494 if ( !has_prep
&& !sfnt_id
[j
][TRICK_SFNT_ID_prep
].Length
)
495 num_matched_ids
[j
]++;
496 if ( num_matched_ids
[j
] == TRICK_SFNT_IDS_PER_FACE
)
505 tt_check_trickyness( FT_Face face
)
510 /* For first, check the face name for quick check. */
511 if ( face
->family_name
&&
512 tt_check_trickyness_family( face
->family_name
) )
515 /* Type42 fonts may lack `name' tables, we thus try to identify */
516 /* tricky fonts by checking the checksums of Type42-persistent */
517 /* sfnt tables (`cvt', `fpgm', and `prep'). */
518 if ( tt_check_trickyness_sfnt_ids( (TT_Face
)face
) )
525 /* Check whether `.notdef' is the only glyph in the `loca' table. */
527 tt_check_single_notdef( FT_Face ttface
)
529 FT_Bool result
= FALSE
;
531 TT_Face face
= (TT_Face
)ttface
;
534 FT_ULong glyph_index
= 0;
538 for( i
= 0; i
< face
->num_locations
; i
++ )
540 tt_face_get_location( face
, i
, &asize
);
550 /* Only have a single outline. */
553 if ( glyph_index
== 0 )
557 /* FIXME: Need to test glyphname == .notdef ? */
562 error
= FT_Get_Glyph_Name( ttface
, glyph_index
, buf
, 8 );
564 buf
[0] == '.' && !ft_strncmp( buf
, ".notdef", 8 ) )
573 /**************************************************************************
579 * Initialize a given TrueType face object.
583 * The source font stream.
586 * The index of the TrueType font, if we are opening a
587 * collection, in bits 0-15. The numbered instance
588 * index~+~1 of a GX (sub)font, if applicable, in bits
592 * Number of additional generic parameters. Ignored.
595 * Additional generic parameters. Ignored.
599 * The newly built face object.
602 * FreeType error code. 0 means success.
604 FT_LOCAL_DEF( FT_Error
)
605 tt_face_init( FT_Stream stream
,
606 FT_Face ttface
, /* TT_Face */
609 FT_Parameter
* params
)
614 TT_Face face
= (TT_Face
)ttface
;
617 FT_TRACE2(( "TTF driver\n" ));
619 library
= ttface
->driver
->root
.library
;
621 sfnt
= (SFNT_Service
)FT_Get_Module_Interface( library
, "sfnt" );
624 FT_ERROR(( "tt_face_init: cannot access `sfnt' module\n" ));
625 error
= FT_THROW( Missing_Module
);
629 /* create input stream from resource */
630 if ( FT_STREAM_SEEK( 0 ) )
633 /* check that we have a valid TrueType file */
635 error
= sfnt
->init_face( stream
, face
, face_index
, num_params
, params
);
637 /* Stream may have changed. */
638 stream
= face
->root
.stream
;
643 /* We must also be able to accept Mac/GX fonts, as well as OT ones. */
644 /* The 0x00020000 tag is completely undocumented; some fonts from */
645 /* Arphic made for Chinese Windows 3.1 have this. */
646 if ( face
->format_tag
!= 0x00010000L
&& /* MS fonts */
647 face
->format_tag
!= 0x00020000L
&& /* CJK fonts for Win 3.1 */
648 face
->format_tag
!= TTAG_true
&& /* Mac fonts */
649 face
->format_tag
!= TTAG_0xA5kbd
&& /* `Keyboard.dfont' (legacy Mac OS X) */
650 face
->format_tag
!= TTAG_0xA5lst
) /* `LastResort.dfont' (legacy Mac OS X) */
652 FT_TRACE2(( " not a TTF font\n" ));
656 #ifdef TT_USE_BYTECODE_INTERPRETER
657 ttface
->face_flags
|= FT_FACE_FLAG_HINTER
;
660 /* If we are performing a simple font format check, exit immediately. */
661 if ( face_index
< 0 )
664 /* Load font directory */
665 error
= sfnt
->load_face( stream
, face
, face_index
, num_params
, params
);
669 if ( tt_check_trickyness( ttface
) )
670 ttface
->face_flags
|= FT_FACE_FLAG_TRICKY
;
672 error
= tt_face_load_hdmx( face
, stream
);
676 if ( FT_IS_SCALABLE( ttface
) )
678 #ifdef FT_CONFIG_OPTION_INCREMENTAL
679 if ( !ttface
->internal
->incremental_interface
)
682 error
= tt_face_load_loca( face
, stream
);
684 /* having a (non-zero) `glyf' table without */
685 /* a `loca' table is not valid */
686 if ( face
->glyf_len
&& FT_ERR_EQ( error
, Table_Missing
) )
692 /* `fpgm', `cvt', and `prep' are optional */
693 error
= tt_face_load_cvt( face
, stream
);
694 if ( error
&& FT_ERR_NEQ( error
, Table_Missing
) )
697 error
= tt_face_load_fpgm( face
, stream
);
698 if ( error
&& FT_ERR_NEQ( error
, Table_Missing
) )
701 error
= tt_face_load_prep( face
, stream
);
702 if ( error
&& FT_ERR_NEQ( error
, Table_Missing
) )
705 /* Check the scalable flag based on `loca'. */
706 #ifdef FT_CONFIG_OPTION_INCREMENTAL
707 if ( !ttface
->internal
->incremental_interface
)
710 if ( ttface
->num_fixed_sizes
&&
711 face
->glyph_locations
&&
712 tt_check_single_notdef( ttface
) )
714 FT_TRACE5(( "tt_face_init:"
715 " Only the `.notdef' glyph has an outline.\n"
717 " Resetting scalable flag to FALSE.\n" ));
719 ttface
->face_flags
&= ~FT_FACE_FLAG_SCALABLE
;
724 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
727 FT_UInt instance_index
= (FT_UInt
)face_index
>> 16;
730 if ( FT_HAS_MULTIPLE_MASTERS( ttface
) &&
733 error
= TT_Set_Named_Instance( face
, instance_index
);
737 tt_apply_mvar( face
);
741 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
743 /* initialize standard glyph loading routines */
744 TT_Init_Glyph_Loading( face
);
750 error
= FT_THROW( Unknown_File_Format
);
755 /**************************************************************************
761 * Finalize a given face object.
765 * A pointer to the face object to destroy.
768 tt_face_done( FT_Face ttface
) /* TT_Face */
770 TT_Face face
= (TT_Face
)ttface
;
779 memory
= ttface
->memory
;
780 stream
= ttface
->stream
;
781 sfnt
= (SFNT_Service
)face
->sfnt
;
783 /* for `extended TrueType formats' (i.e. compressed versions) */
784 if ( face
->extra
.finalizer
)
785 face
->extra
.finalizer( face
->extra
.data
);
788 sfnt
->done_face( face
);
790 /* freeing the locations table */
791 tt_face_done_loca( face
);
793 tt_face_free_hdmx( face
);
795 /* freeing the CVT */
796 FT_FREE( face
->cvt
);
799 /* freeing the programs */
800 FT_FRAME_RELEASE( face
->font_program
);
801 FT_FRAME_RELEASE( face
->cvt_program
);
802 face
->font_program_size
= 0;
803 face
->cvt_program_size
= 0;
805 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
806 tt_done_blend( face
);
812 /**************************************************************************
818 #ifdef TT_USE_BYTECODE_INTERPRETER
820 /**************************************************************************
826 * Run the font program.
830 * A handle to the size object.
833 * Set if bytecode execution should be pedantic.
836 * FreeType error code. 0 means success.
838 FT_LOCAL_DEF( FT_Error
)
839 tt_size_run_fpgm( TT_Size size
,
842 TT_Face face
= (TT_Face
)size
->root
.face
;
847 exec
= size
->context
;
849 error
= TT_Load_Context( exec
, face
, size
);
860 exec
->instruction_trap
= FALSE
;
861 exec
->F_dot_P
= 0x4000L
;
863 exec
->pedantic_hinting
= pedantic
;
866 FT_Size_Metrics
* size_metrics
= &exec
->metrics
;
867 TT_Size_Metrics
* tt_metrics
= &exec
->tt_metrics
;
870 size_metrics
->x_ppem
= 0;
871 size_metrics
->y_ppem
= 0;
872 size_metrics
->x_scale
= 0;
873 size_metrics
->y_scale
= 0;
875 tt_metrics
->ppem
= 0;
876 tt_metrics
->scale
= 0;
877 tt_metrics
->ratio
= 0x10000L
;
880 /* allow font program execution */
881 TT_Set_CodeRange( exec
,
884 (FT_Long
)face
->font_program_size
);
886 /* disable CVT and glyph programs coderange */
887 TT_Clear_CodeRange( exec
, tt_coderange_cvt
);
888 TT_Clear_CodeRange( exec
, tt_coderange_glyph
);
890 if ( face
->font_program_size
> 0 )
892 TT_Goto_CodeRange( exec
, tt_coderange_font
, 0 );
894 FT_TRACE4(( "Executing `fpgm' table.\n" ));
895 error
= face
->interpreter( exec
);
896 #ifdef FT_DEBUG_LEVEL_TRACE
898 FT_TRACE4(( " interpretation failed with error code 0x%x\n",
905 size
->bytecode_ready
= error
;
908 TT_Save_Context( exec
, size
);
914 /**************************************************************************
920 * Run the control value program.
924 * A handle to the size object.
927 * Set if bytecode execution should be pedantic.
930 * FreeType error code. 0 means success.
932 FT_LOCAL_DEF( FT_Error
)
933 tt_size_run_prep( TT_Size size
,
936 TT_Face face
= (TT_Face
)size
->root
.face
;
941 /* unscaled CVT values are already stored in 26.6 format */
942 FT_Fixed scale
= size
->ttmetrics
.scale
>> 6;
945 /* Scale the cvt values to the new ppem. */
946 /* By default, we use the y ppem value for scaling. */
947 FT_TRACE6(( "CVT values:\n" ));
948 for ( i
= 0; i
< size
->cvt_size
; i
++ )
950 size
->cvt
[i
] = FT_MulFix( face
->cvt
[i
], scale
);
951 FT_TRACE6(( " %3d: %f (%f)\n",
952 i
, face
->cvt
[i
] / 64.0, size
->cvt
[i
] / 64.0 ));
956 exec
= size
->context
;
958 error
= TT_Load_Context( exec
, face
, size
);
965 exec
->instruction_trap
= FALSE
;
967 exec
->pedantic_hinting
= pedantic
;
969 TT_Set_CodeRange( exec
,
972 (FT_Long
)face
->cvt_program_size
);
974 TT_Clear_CodeRange( exec
, tt_coderange_glyph
);
976 if ( face
->cvt_program_size
> 0 )
978 TT_Goto_CodeRange( exec
, tt_coderange_cvt
, 0 );
980 FT_TRACE4(( "Executing `prep' table.\n" ));
981 error
= face
->interpreter( exec
);
982 #ifdef FT_DEBUG_LEVEL_TRACE
984 FT_TRACE4(( " interpretation failed with error code 0x%x\n",
991 size
->cvt_ready
= error
;
993 /* UNDOCUMENTED! The MS rasterizer doesn't allow the following */
994 /* graphics state variables to be modified by the CVT program. */
996 exec
->GS
.dualVector
.x
= 0x4000;
997 exec
->GS
.dualVector
.y
= 0;
998 exec
->GS
.projVector
.x
= 0x4000;
999 exec
->GS
.projVector
.y
= 0x0;
1000 exec
->GS
.freeVector
.x
= 0x4000;
1001 exec
->GS
.freeVector
.y
= 0x0;
1013 /* save as default graphics state */
1014 size
->GS
= exec
->GS
;
1016 TT_Save_Context( exec
, size
);
1023 tt_size_done_bytecode( FT_Size ftsize
)
1025 TT_Size size
= (TT_Size
)ftsize
;
1026 TT_Face face
= (TT_Face
)ftsize
->face
;
1027 FT_Memory memory
= face
->root
.memory
;
1029 if ( size
->context
)
1031 TT_Done_Context( size
->context
);
1032 size
->context
= NULL
;
1035 FT_FREE( size
->cvt
);
1038 /* free storage area */
1039 FT_FREE( size
->storage
);
1040 size
->storage_size
= 0;
1043 tt_glyphzone_done( &size
->twilight
);
1045 FT_FREE( size
->function_defs
);
1046 FT_FREE( size
->instruction_defs
);
1048 size
->num_function_defs
= 0;
1049 size
->max_function_defs
= 0;
1050 size
->num_instruction_defs
= 0;
1051 size
->max_instruction_defs
= 0;
1056 size
->bytecode_ready
= -1;
1057 size
->cvt_ready
= -1;
1061 /* Initialize bytecode-related fields in the size object. */
1062 /* We do this only if bytecode interpretation is really needed. */
1064 tt_size_init_bytecode( FT_Size ftsize
,
1068 TT_Size size
= (TT_Size
)ftsize
;
1069 TT_Face face
= (TT_Face
)ftsize
->face
;
1070 FT_Memory memory
= face
->root
.memory
;
1072 FT_UShort n_twilight
;
1073 TT_MaxProfile
* maxp
= &face
->max_profile
;
1076 /* clean up bytecode related data */
1077 FT_FREE( size
->function_defs
);
1078 FT_FREE( size
->instruction_defs
);
1079 FT_FREE( size
->cvt
);
1080 FT_FREE( size
->storage
);
1082 if ( size
->context
)
1083 TT_Done_Context( size
->context
);
1084 tt_glyphzone_done( &size
->twilight
);
1086 size
->bytecode_ready
= -1;
1087 size
->cvt_ready
= -1;
1089 size
->context
= TT_New_Context( (TT_Driver
)face
->root
.driver
);
1091 size
->max_function_defs
= maxp
->maxFunctionDefs
;
1092 size
->max_instruction_defs
= maxp
->maxInstructionDefs
;
1094 size
->num_function_defs
= 0;
1095 size
->num_instruction_defs
= 0;
1100 size
->cvt_size
= face
->cvt_size
;
1101 size
->storage_size
= maxp
->maxStorage
;
1103 /* Set default metrics */
1105 TT_Size_Metrics
* tt_metrics
= &size
->ttmetrics
;
1108 tt_metrics
->rotated
= FALSE
;
1109 tt_metrics
->stretched
= FALSE
;
1111 /* Set default engine compensation. Value 3 is not described */
1112 /* in the OpenType specification (as of Mai 2019), but Greg */
1113 /* says that MS handles it the same as `gray'. */
1115 /* The Apple specification says that the compensation for */
1116 /* `gray' is always zero. FreeType doesn't do any */
1117 /* compensation at all. */
1118 tt_metrics
->compensations
[0] = 0; /* gray */
1119 tt_metrics
->compensations
[1] = 0; /* black */
1120 tt_metrics
->compensations
[2] = 0; /* white */
1121 tt_metrics
->compensations
[3] = 0; /* zero */
1124 /* allocate function defs, instruction defs, cvt, and storage area */
1125 if ( FT_NEW_ARRAY( size
->function_defs
, size
->max_function_defs
) ||
1126 FT_NEW_ARRAY( size
->instruction_defs
, size
->max_instruction_defs
) ||
1127 FT_NEW_ARRAY( size
->cvt
, size
->cvt_size
) ||
1128 FT_NEW_ARRAY( size
->storage
, size
->storage_size
) )
1131 /* reserve twilight zone */
1132 n_twilight
= maxp
->maxTwilightPoints
;
1134 /* there are 4 phantom points (do we need this?) */
1137 error
= tt_glyphzone_new( memory
, n_twilight
, 0, &size
->twilight
);
1141 size
->twilight
.n_points
= n_twilight
;
1143 size
->GS
= tt_default_graphics_state
;
1145 /* set `face->interpreter' according to the debug hook present */
1147 FT_Library library
= face
->root
.driver
->root
.library
;
1150 face
->interpreter
= (TT_Interpreter
)
1151 library
->debug_hooks
[FT_DEBUG_HOOK_TRUETYPE
];
1152 if ( !face
->interpreter
)
1153 face
->interpreter
= (TT_Interpreter
)TT_RunIns
;
1156 /* Fine, now run the font program! */
1158 /* In case of an error while executing `fpgm', we intentionally don't */
1159 /* clean up immediately – bugs in the `fpgm' are so fundamental that */
1160 /* all following hinting calls should fail. Additionally, `fpgm' is */
1161 /* to be executed just once; calling it again is completely useless */
1162 /* and might even lead to extremely slow behaviour if it is malformed */
1163 /* (containing an infinite loop, for example). */
1164 error
= tt_size_run_fpgm( size
, pedantic
);
1169 tt_size_done_bytecode( ftsize
);
1175 FT_LOCAL_DEF( FT_Error
)
1176 tt_size_ready_bytecode( TT_Size size
,
1179 FT_Error error
= FT_Err_Ok
;
1182 if ( size
->bytecode_ready
< 0 )
1183 error
= tt_size_init_bytecode( (FT_Size
)size
, pedantic
);
1185 error
= size
->bytecode_ready
;
1190 /* rescale CVT when needed */
1191 if ( size
->cvt_ready
< 0 )
1196 /* all twilight points are originally zero */
1197 for ( i
= 0; i
< (FT_UInt
)size
->twilight
.n_points
; i
++ )
1199 size
->twilight
.org
[i
].x
= 0;
1200 size
->twilight
.org
[i
].y
= 0;
1201 size
->twilight
.cur
[i
].x
= 0;
1202 size
->twilight
.cur
[i
].y
= 0;
1205 /* clear storage area */
1206 for ( i
= 0; i
< (FT_UInt
)size
->storage_size
; i
++ )
1207 size
->storage
[i
] = 0;
1209 size
->GS
= tt_default_graphics_state
;
1211 error
= tt_size_run_prep( size
, pedantic
);
1214 error
= size
->cvt_ready
;
1220 #endif /* TT_USE_BYTECODE_INTERPRETER */
1223 /**************************************************************************
1229 * Initialize a new TrueType size object.
1233 * A handle to the size object.
1236 * FreeType error code. 0 means success.
1238 FT_LOCAL_DEF( FT_Error
)
1239 tt_size_init( FT_Size ttsize
) /* TT_Size */
1241 TT_Size size
= (TT_Size
)ttsize
;
1242 FT_Error error
= FT_Err_Ok
;
1245 #ifdef TT_USE_BYTECODE_INTERPRETER
1246 size
->bytecode_ready
= -1;
1247 size
->cvt_ready
= -1;
1250 size
->ttmetrics
.valid
= FALSE
;
1251 size
->strike_index
= 0xFFFFFFFFUL
;
1257 /**************************************************************************
1263 * The TrueType size object finalizer.
1267 * A handle to the target size object.
1269 FT_LOCAL_DEF( void )
1270 tt_size_done( FT_Size ttsize
) /* TT_Size */
1272 TT_Size size
= (TT_Size
)ttsize
;
1275 #ifdef TT_USE_BYTECODE_INTERPRETER
1276 tt_size_done_bytecode( ttsize
);
1279 size
->ttmetrics
.valid
= FALSE
;
1283 /**************************************************************************
1289 * Reset a TrueType size when resolutions and character dimensions
1290 * have been changed.
1294 * A handle to the target size object.
1297 * Only recompute ascender, descender, and height;
1298 * this flag is used for variation fonts where
1299 * `tt_size_reset' is used as an iterator function.
1301 FT_LOCAL_DEF( FT_Error
)
1302 tt_size_reset( TT_Size size
,
1303 FT_Bool only_height
)
1306 FT_Size_Metrics
* size_metrics
;
1309 face
= (TT_Face
)size
->root
.face
;
1311 /* nothing to do for CFF2 */
1312 if ( face
->is_cff2
)
1315 size
->ttmetrics
.valid
= FALSE
;
1317 size_metrics
= &size
->hinted_metrics
;
1319 /* copy the result from base layer */
1320 *size_metrics
= size
->root
.metrics
;
1322 if ( size_metrics
->x_ppem
< 1 || size_metrics
->y_ppem
< 1 )
1323 return FT_THROW( Invalid_PPem
);
1325 /* This bit flag, if set, indicates that the ppems must be */
1326 /* rounded to integers. Nearly all TrueType fonts have this bit */
1327 /* set, as hinting won't work really well otherwise. */
1329 if ( face
->header
.Flags
& 8 )
1331 /* the TT spec always asks for ROUND, not FLOOR or CEIL */
1332 size_metrics
->ascender
= FT_PIX_ROUND(
1333 FT_MulFix( face
->root
.ascender
,
1334 size_metrics
->y_scale
) );
1335 size_metrics
->descender
= FT_PIX_ROUND(
1336 FT_MulFix( face
->root
.descender
,
1337 size_metrics
->y_scale
) );
1338 size_metrics
->height
= FT_PIX_ROUND(
1339 FT_MulFix( face
->root
.height
,
1340 size_metrics
->y_scale
) );
1343 size
->ttmetrics
.valid
= TRUE
;
1347 /* we must not recompute the scaling values here since */
1348 /* `tt_size_reset' was already called (with only_height = 0) */
1352 if ( face
->header
.Flags
& 8 )
1354 /* base scaling values on integer ppem values, */
1355 /* as mandated by the TrueType specification */
1356 size_metrics
->x_scale
= FT_DivFix( size_metrics
->x_ppem
<< 6,
1357 face
->root
.units_per_EM
);
1358 size_metrics
->y_scale
= FT_DivFix( size_metrics
->y_ppem
<< 6,
1359 face
->root
.units_per_EM
);
1361 size_metrics
->max_advance
= FT_PIX_ROUND(
1362 FT_MulFix( face
->root
.max_advance_width
,
1363 size_metrics
->x_scale
) );
1366 /* compute new transformation */
1367 if ( size_metrics
->x_ppem
>= size_metrics
->y_ppem
)
1369 size
->ttmetrics
.scale
= size_metrics
->x_scale
;
1370 size
->ttmetrics
.ppem
= size_metrics
->x_ppem
;
1371 size
->ttmetrics
.x_ratio
= 0x10000L
;
1372 size
->ttmetrics
.y_ratio
= FT_DivFix( size_metrics
->y_ppem
,
1373 size_metrics
->x_ppem
);
1377 size
->ttmetrics
.scale
= size_metrics
->y_scale
;
1378 size
->ttmetrics
.ppem
= size_metrics
->y_ppem
;
1379 size
->ttmetrics
.x_ratio
= FT_DivFix( size_metrics
->x_ppem
,
1380 size_metrics
->y_ppem
);
1381 size
->ttmetrics
.y_ratio
= 0x10000L
;
1384 size
->metrics
= size_metrics
;
1386 #ifdef TT_USE_BYTECODE_INTERPRETER
1387 size
->cvt_ready
= -1;
1388 #endif /* TT_USE_BYTECODE_INTERPRETER */
1394 /**************************************************************************
1400 * Initialize a given TrueType driver object.
1404 * A handle to the target driver object.
1407 * FreeType error code. 0 means success.
1409 FT_LOCAL_DEF( FT_Error
)
1410 tt_driver_init( FT_Module ttdriver
) /* TT_Driver */
1413 #ifdef TT_USE_BYTECODE_INTERPRETER
1415 TT_Driver driver
= (TT_Driver
)ttdriver
;
1417 driver
->interpreter_version
= TT_INTERPRETER_VERSION_35
;
1418 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
1419 driver
->interpreter_version
= TT_INTERPRETER_VERSION_38
;
1421 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
1422 driver
->interpreter_version
= TT_INTERPRETER_VERSION_40
;
1425 #else /* !TT_USE_BYTECODE_INTERPRETER */
1427 FT_UNUSED( ttdriver
);
1429 #endif /* !TT_USE_BYTECODE_INTERPRETER */
1435 /**************************************************************************
1441 * Finalize a given TrueType driver.
1445 * A handle to the target TrueType driver.
1447 FT_LOCAL_DEF( void )
1448 tt_driver_done( FT_Module ttdriver
) /* TT_Driver */
1450 FT_UNUSED( ttdriver
);
1454 /**************************************************************************
1460 * Initialize a new slot object.
1464 * A handle to the slot object.
1467 * FreeType error code. 0 means success.
1469 FT_LOCAL_DEF( FT_Error
)
1470 tt_slot_init( FT_GlyphSlot slot
)
1472 return FT_GlyphLoader_CreateExtra( slot
->internal
->loader
);