30#ifdef TT_USE_BYTECODE_INTERPRETER
34#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
45#define FT_COMPONENT ttobjs
48#ifdef TT_USE_BYTECODE_INTERPRETER
70 tt_glyphzone_done( FT_Memory memory,
105 FT_LOCAL_DEF( FT_Error )
106 tt_glyphzone_new( FT_Memory memory,
108 FT_UShort maxContours,
112 FT_Long size = 3 * maxPoints *
sizeof ( FT_Vector ) +
113 maxContours *
sizeof ( FT_UShort ) +
114 maxPoints *
sizeof ( FT_Byte );
117 if ( !FT_ALLOC( zone->org, size ) )
119 zone->n_points = maxPoints;
120 zone->n_contours = maxContours;
122 zone->cur = zone->org + maxPoints;
123 zone->orus = zone->cur + maxPoints;
124 zone->contours = (FT_UShort*)( zone->orus + maxPoints );
125 zone->tags = (FT_Byte*)( zone->contours + maxContours );
127 zone->first_point = 0;
141 static const FT_String*
142 tt_skip_pdffont_random_tag(
const FT_String* name )
144 if ( ft_isupper( name[0] ) &&
145 ft_isupper( name[1] ) &&
146 ft_isupper( name[2] ) &&
147 ft_isupper( name[3] ) &&
148 ft_isupper( name[4] ) &&
149 ft_isupper( name[5] ) &&
153 FT_TRACE7((
"name without randomization tag: %s\n", name + 7 ));
165 tt_check_trickyness_family(
const FT_String* name )
168#define TRICK_NAMES_MAX_CHARACTERS 19
169#define TRICK_NAMES_COUNT 20
171 static const char trick_names[TRICK_NAMES_COUNT]
172 [TRICK_NAMES_MAX_CHARACTERS + 1] =
213 "Ming(for ISO10646)",
223 const FT_String* name_without_tag;
226 name_without_tag = tt_skip_pdffont_random_tag( name );
227 for ( nn = 0; nn < TRICK_NAMES_COUNT; nn++ )
228 if ( ft_strstr( name_without_tag, trick_names[nn] ) )
243 tt_synth_sfnt_checksum( FT_Stream stream,
247 FT_UInt32 checksum = 0;
252 if ( FT_FRAME_ENTER( length ) )
255 p = (FT_Byte*)stream->cursor;
257 for ( ; length > 3; length -= 4 )
258 checksum += FT_NEXT_ULONG( p );
260 for ( shift = 24; length > 0; length--, shift -=8 )
261 checksum += (FT_UInt32)FT_NEXT_BYTE( p ) << shift;
272 tt_get_sfnt_checksum( TT_Face face,
276 if ( face->dir_tables[i].CheckSum )
277 return face->dir_tables[i].CheckSum;
280 if ( !face->goto_table )
283 if ( face->goto_table( face,
284 face->dir_tables[i].Tag,
289 return (FT_ULong)tt_synth_sfnt_checksum( face->root.stream,
290 face->dir_tables[i].Length );
294 typedef struct tt_sfnt_id_rec_
303 tt_check_trickyness_sfnt_ids( TT_Face face )
305#define TRICK_SFNT_IDS_PER_FACE 3
306#define TRICK_SFNT_IDS_NUM_FACES 31
308 static const tt_sfnt_id_rec sfnt_id[TRICK_SFNT_IDS_NUM_FACES]
309 [TRICK_SFNT_IDS_PER_FACE] =
312#define TRICK_SFNT_ID_cvt 0
313#define TRICK_SFNT_ID_fpgm 1
314#define TRICK_SFNT_ID_prep 2
317 { 0x05BCF058UL, 0x000002E4UL },
318 { 0x28233BF1UL, 0x000087C4UL },
319 { 0xA344A1EAUL, 0x000001E1UL }
322 { 0x05BCF058UL, 0x000002E4UL },
323 { 0x28233BF1UL, 0x000087C4UL },
324 { 0xA344A1EBUL, 0x000001E1UL }
327 { 0x12C3EBB2UL, 0x00000350UL },
328 { 0xB680EE64UL, 0x000087A7UL },
329 { 0xCE939563UL, 0x00000758UL }
332 { 0x11E5EAD4UL, 0x00000350UL },
333 { 0xCE5956E9UL, 0x0000BC85UL },
334 { 0x8272F416UL, 0x00000045UL }
337 { 0x1257EB46UL, 0x00000350UL },
338 { 0xF699D160UL, 0x0000715FUL },
339 { 0xD222F568UL, 0x000003BCUL }
342 { 0x1262EB4EUL, 0x00000350UL },
343 { 0xE86A5D64UL, 0x00007940UL },
344 { 0x7850F729UL, 0x000005FFUL }
347 { 0x122DEB0AUL, 0x00000350UL },
348 { 0x3D16328AUL, 0x0000859BUL },
349 { 0xA93FC33BUL, 0x000002CBUL }
352 { 0x125FEB26UL, 0x00000350UL },
353 { 0xA5ACC982UL, 0x00007EE1UL },
354 { 0x90999196UL, 0x0000041FUL }
357 { 0x11E5EAD4UL, 0x00000350UL },
358 { 0x5A30CA3BUL, 0x00009063UL },
359 { 0x13A42602UL, 0x0000007EUL }
362 { 0x11E5EAD4UL, 0x00000350UL },
363 { 0xA6E78C01UL, 0x00008998UL },
364 { 0x13A42602UL, 0x0000007EUL }
367 { 0x11E5EAD4UL, 0x00000360UL },
368 { 0x9DB282B2UL, 0x0000C06EUL },
369 { 0x53E6D7CAUL, 0x00000082UL }
372 { 0x1243EB18UL, 0x00000350UL },
373 { 0xBA0A8C30UL, 0x000074ADUL },
374 { 0xF3D83409UL, 0x0000037BUL }
377 { 0x07DCF546UL, 0x00000308UL },
378 { 0x40FE7C90UL, 0x00008E2AUL },
379 { 0x608174B5UL, 0x0000007AUL }
382 { 0xEB891238UL, 0x00000308UL },
383 { 0xD2E4DCD4UL, 0x0000676FUL },
384 { 0x8EA5F293UL, 0x000003B8UL }
387 { 0xFFFBFFFCUL, 0x00000008UL },
388 { 0x9C9E48B8UL, 0x0000BEA2UL },
389 { 0x70020112UL, 0x00000008UL }
392 { 0xFFFBFFFCUL, 0x00000008UL },
393 { 0x0A5A0483UL, 0x00017C39UL },
394 { 0x70020112UL, 0x00000008UL }
397 { 0x00000000UL, 0x00000000UL },
398 { 0x40C92555UL, 0x000000E5UL },
399 { 0xA39B58E3UL, 0x0000117CUL }
402 { 0x00000000UL, 0x00000000UL },
403 { 0x33C41652UL, 0x000000E5UL },
404 { 0x26D6C52AUL, 0x00000F6AUL }
407 { 0x00000000UL, 0x00000000UL },
408 { 0x6DB1651DUL, 0x0000019DUL },
409 { 0x6C6E4B03UL, 0x00002492UL }
412 { 0x00000000UL, 0x00000000UL },
413 { 0x40C92555UL, 0x000000E5UL },
414 { 0xDE51FAD0UL, 0x0000117CUL }
417 { 0x00000000UL, 0x00000000UL },
418 { 0x85E47664UL, 0x000000E5UL },
419 { 0xA6C62831UL, 0x00001CAAUL }
422 { 0x00000000UL, 0x00000000UL },
423 { 0x2D891CFDUL, 0x0000019DUL },
424 { 0xA0604633UL, 0x00001DE8UL }
427 { 0x00000000UL, 0x00000000UL },
428 { 0x40AA774CUL, 0x000001CBUL },
429 { 0x9B5CAA96UL, 0x00001F9AUL }
432 { 0x00000000UL, 0x00000000UL },
433 { 0x0D3DE9CBUL, 0x00000141UL },
434 { 0xD4127766UL, 0x00002280UL }
437 { 0x00000000UL, 0x00000000UL },
438 { 0x4A692698UL, 0x000001F0UL },
439 { 0x340D4346UL, 0x00001FCAUL }
442 { 0x00000000UL, 0x00000000UL },
443 { 0xCD34C604UL, 0x00000166UL },
444 { 0x6CF31046UL, 0x000022B0UL }
447 { 0x00000000UL, 0x00000000UL },
448 { 0x5DA75315UL, 0x0000019DUL },
449 { 0x40745A5FUL, 0x000022E0UL }
452 { 0x00000000UL, 0x00000000UL },
453 { 0xF055FC48UL, 0x000001C2UL },
454 { 0x3900DED3UL, 0x00001E18UL }
457 { 0x00170003UL, 0x00000060UL },
458 { 0xDBB4306EUL, 0x000058AAUL },
459 { 0xD643482AUL, 0x00000035UL }
462 { 0x1269EB58UL, 0x00000350UL },
463 { 0x5CD5957AUL, 0x00006A4EUL },
464 { 0xF758323AUL, 0x00000380UL }
467 { 0x122FEB0BUL, 0x00000350UL },
468 { 0x7F10919AUL, 0x000070A9UL },
469 { 0x7CD7E7B7UL, 0x0000025CUL }
474 int num_matched_ids[TRICK_SFNT_IDS_NUM_FACES];
475 FT_Bool has_cvt, has_fpgm, has_prep;
480 FT_ARRAY_ZERO( num_matched_ids, TRICK_SFNT_IDS_NUM_FACES );
485 for ( i = 0; i < face->num_tables; i++ )
489 switch( face->dir_tables[i].Tag )
492 k = TRICK_SFNT_ID_cvt;
497 k = TRICK_SFNT_ID_fpgm;
502 k = TRICK_SFNT_ID_prep;
510 for ( j = 0; j < TRICK_SFNT_IDS_NUM_FACES; j++ )
511 if ( face->dir_tables[i].Length == sfnt_id[j][k].Length )
514 checksum = tt_get_sfnt_checksum( face, i );
516 if ( sfnt_id[j][k].CheckSum == checksum )
517 num_matched_ids[j]++;
519 if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE )
524 for ( j = 0; j < TRICK_SFNT_IDS_NUM_FACES; j++ )
526 if ( !has_cvt && !sfnt_id[j][TRICK_SFNT_ID_cvt].Length )
527 num_matched_ids[j]++;
528 if ( !has_fpgm && !sfnt_id[j][TRICK_SFNT_ID_fpgm].Length )
529 num_matched_ids[j]++;
530 if ( !has_prep && !sfnt_id[j][TRICK_SFNT_ID_prep].Length )
531 num_matched_ids[j]++;
532 if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE )
541 tt_check_trickyness( FT_Face face )
547 if ( face->family_name &&
548 tt_check_trickyness_family( face->family_name ) )
550 FT_TRACE3((
"found as a tricky font"
551 " by its family name: %s\n", face->family_name ));
558 if ( tt_check_trickyness_sfnt_ids( (TT_Face)face ) )
560 FT_TRACE3((
"found as a tricky font"
561 " by its cvt/fpgm/prep table checksum\n" ));
573 tt_check_single_notdef( FT_Face ttface )
575 FT_Bool result = FALSE;
577 TT_Face face = (TT_Face)ttface;
580 FT_ULong glyph_index = 0;
584 for( i = 0; i < face->num_locations; i++ )
586 tt_face_get_location( ttface, i, &asize );
599 if ( glyph_index == 0 )
608 error = FT_Get_Glyph_Name( ttface, glyph_index, buf, 8 );
610 buf[0] ==
'.' && !ft_strncmp( buf,
".notdef", 8 ) )
650 FT_LOCAL_DEF( FT_Error )
651 tt_face_init( FT_Stream stream,
655 FT_Parameter* params )
660 TT_Face face = (TT_Face)ttface;
663 FT_TRACE2((
"TTF driver\n" ));
665 library = ttface->driver->root.library;
667 sfnt = (SFNT_Service)FT_Get_Module_Interface( library,
"sfnt" );
670 FT_ERROR((
"tt_face_init: cannot access `sfnt' module\n" ));
671 error = FT_THROW( Missing_Module );
676 if ( FT_STREAM_SEEK( 0 ) )
681 error = sfnt->init_face( stream, face, face_index, num_params, params );
684 stream = face->root.stream;
692 if ( face->format_tag != 0x00010000L &&
693 face->format_tag != 0x00020000L &&
694 face->format_tag != TTAG_true &&
695 face->format_tag != TTAG_0xA5kbd &&
696 face->format_tag != TTAG_0xA5lst )
698 FT_TRACE2((
" not a TTF font\n" ));
702#ifdef TT_USE_BYTECODE_INTERPRETER
703 ttface->face_flags |= FT_FACE_FLAG_HINTER;
707 if ( face_index < 0 )
711 error = sfnt->load_face( stream, face, face_index, num_params, params );
715#ifdef TT_USE_BYTECODE_INTERPRETER
716 if ( tt_check_trickyness( ttface ) )
717 ttface->face_flags |= FT_FACE_FLAG_TRICKY;
720 error = tt_face_load_hdmx( face, stream );
724 if ( FT_IS_SCALABLE( ttface ) ||
725 FT_HAS_SBIX( ttface ) )
727#ifdef FT_CONFIG_OPTION_INCREMENTAL
728 if ( !ttface->internal->incremental_interface )
731 error = tt_face_load_loca( face, stream );
735 if ( face->glyf_len && FT_ERR_EQ( error, Table_Missing ) )
742 error = tt_face_load_cvt( face, stream );
743 if ( error && FT_ERR_NEQ( error, Table_Missing ) )
746 error = tt_face_load_fpgm( face, stream );
747 if ( error && FT_ERR_NEQ( error, Table_Missing ) )
750 error = tt_face_load_prep( face, stream );
751 if ( error && FT_ERR_NEQ( error, Table_Missing ) )
755#ifdef FT_CONFIG_OPTION_INCREMENTAL
756 if ( !ttface->internal->incremental_interface )
759 if ( ttface->num_fixed_sizes &&
760 face->glyph_locations &&
761 tt_check_single_notdef( ttface ) )
763 FT_TRACE5((
"tt_face_init:"
764 " Only the `.notdef' glyph has an outline.\n" ));
766 " Resetting scalable flag to FALSE.\n" ));
768 ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE;
773#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
775 FT_UInt instance_index = (FT_UInt)face_index >> 16;
778 if ( instance_index && FT_HAS_MULTIPLE_MASTERS( ttface ) )
780 error = FT_Set_Named_Instance( ttface, instance_index );
788 TT_Init_Glyph_Loading( face );
794 error = FT_THROW( Unknown_File_Format );
812 tt_face_done( FT_Face ttface )
814 TT_Face face = (TT_Face)ttface;
823 memory = ttface->memory;
824 stream = ttface->stream;
825 sfnt = (SFNT_Service)face->sfnt;
828 if ( face->extra.finalizer )
829 face->extra.finalizer( face->extra.data );
832 sfnt->done_face( face );
835 tt_face_done_loca( face );
837 tt_face_free_hdmx( face );
840 FT_FREE( face->cvt );
844 FT_FRAME_RELEASE( face->font_program );
845 FT_FRAME_RELEASE( face->cvt_program );
846 face->font_program_size = 0;
847 face->cvt_program_size = 0;
849#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
850 tt_done_blend( ttface );
862#ifdef TT_USE_BYTECODE_INTERPRETER
879 FT_LOCAL_DEF( FT_Error )
880 tt_size_run_fpgm( TT_Size size )
882 TT_Face face = (TT_Face)size->root.face;
883 TT_ExecContext exec = size->context;
887 error = TT_Load_Context( exec, face, size );
892 TT_Clear_CodeRange( exec, tt_coderange_cvt );
893 TT_Clear_CodeRange( exec, tt_coderange_glyph );
895 if ( face->font_program_size > 0 )
898 TT_Set_CodeRange( exec,
901 (FT_Long)face->font_program_size );
903 exec->pts.n_points = 0;
904 exec->pts.n_contours = 0;
906 FT_TRACE4((
"Executing `fpgm' table.\n" ));
907 error = TT_Run_Context( exec, size );
908 FT_TRACE4(( error ?
" failed (error code 0x%x)\n" :
"",
914 size->bytecode_ready = error;
917 TT_Save_Context( exec, size );
938 FT_LOCAL_DEF( FT_Error )
939 tt_size_run_prep( TT_Size size )
941 TT_Face face = (TT_Face)size->root.face;
942 TT_ExecContext exec = size->context;
949 size->GS = tt_default_graphics_state;
952 FT_ARRAY_ZERO( size->twilight.org, size->twilight.n_points );
953 FT_ARRAY_ZERO( size->twilight.cur, size->twilight.n_points );
955 error = TT_Load_Context( exec, face, size );
960 FT_ARRAY_ZERO( exec->storage, exec->storeSize );
964 FT_TRACE6((
"CVT values:\n" ));
965 for ( i = 0; i < exec->cvtSize; i++ )
970 exec->cvt[i] = FT_MulFix( face->cvt[i] / 64, size->ttmetrics.scale );
971 FT_TRACE6((
" %3u: %f (%f)\n",
972 i, (
double)face->cvt[i] / 64, (
double)exec->cvt[i] / 64 ));
976 TT_Clear_CodeRange( exec, tt_coderange_glyph );
978 if ( face->cvt_program_size > 0 )
981 TT_Set_CodeRange( exec,
984 (FT_Long)face->cvt_program_size );
986 exec->pts.n_points = 0;
987 exec->pts.n_contours = 0;
989 FT_TRACE4((
"Executing `prep' table.\n" ));
990 error = TT_Run_Context( exec, size );
991 FT_TRACE4(( error ?
" failed (error code 0x%x)\n" :
"",
997 size->cvt_ready = error;
1000 TT_Save_Context( exec, size );
1007 tt_size_done_bytecode( TT_Size size )
1009 FT_Memory memory = size->root.face->memory;
1010 TT_ExecContext exec = size->context;
1015 FT_FREE( exec->stack );
1016 FT_FREE( exec->FDefs );
1018 TT_Done_Context( exec );
1019 size->context = NULL;
1023 tt_glyphzone_done( memory, &size->twilight );
1029 FT_LOCAL_DEF( FT_Error )
1030 tt_size_init_bytecode( TT_Size size,
1034 TT_Face face = (TT_Face)size->root.face;
1035 FT_Memory memory = size->root.face->memory;
1037 FT_UShort n_twilight;
1038 TT_MaxProfile* maxp = &face->max_profile;
1039 TT_ExecContext exec;
1042 exec = TT_New_Context( (TT_Driver)face->root.driver );
1044 return FT_THROW( Could_Not_Find_Context );
1046 exec->pedantic_hinting = pedantic;
1048 exec->maxFDefs = maxp->maxFunctionDefs;
1049 exec->maxIDefs = maxp->maxInstructionDefs;
1051 if ( FT_NEW_ARRAY( exec->FDefs, exec->maxFDefs + exec->maxIDefs ) )
1054 exec->IDefs = exec->FDefs + exec->maxFDefs;
1064 exec->stackSize = maxp->maxStackElements + 32;
1065 exec->storeSize = maxp->maxStorage;
1066 exec->cvtSize = face->cvt_size;
1068 if ( FT_NEW_ARRAY( exec->stack,
1070 (FT_Long)( exec->storeSize + exec->cvtSize ) ) )
1075 n_twilight = maxp->maxTwilightPoints;
1080 error = tt_glyphzone_new( memory, n_twilight, 0, &size->twilight );
1084 size->GS = tt_default_graphics_state;
1085 size->cvt_ready = -1;
1086 size->context = exec;
1088 size->ttmetrics.rotated = FALSE;
1089 size->ttmetrics.stretched = FALSE;
1099 error = tt_size_run_fpgm( size );
1104 tt_size_done_bytecode( size );
1127 FT_LOCAL_DEF( FT_Error )
1128 tt_size_init( FT_Size ttsize )
1130 TT_Size size = (TT_Size)ttsize;
1131 FT_Error error = FT_Err_Ok;
1134#ifdef TT_USE_BYTECODE_INTERPRETER
1135 size->bytecode_ready = -1;
1138 size->strike_index = 0xFFFFFFFFUL;
1156 FT_LOCAL_DEF(
void )
1157 tt_size_done( FT_Size ttsize )
1159#ifdef TT_USE_BYTECODE_INTERPRETER
1160 tt_size_done_bytecode( (TT_Size)ttsize );
1162 FT_UNUSED( ttsize );
1184 FT_LOCAL_DEF(
void )
1185 tt_size_reset_height( FT_Size ft_size )
1187 TT_Size size = (TT_Size)ft_size;
1188 TT_Face face = (TT_Face)ft_size->face;
1189 FT_Size_Metrics* size_metrics = &size->hinted_metrics;
1195 if ( face->header.Flags & 8 )
1198 size_metrics->ascender = FT_PIX_ROUND(
1199 FT_MulFix( face->root.ascender,
1200 size_metrics->y_scale ) );
1201 size_metrics->descender = FT_PIX_ROUND(
1202 FT_MulFix( face->root.descender,
1203 size_metrics->y_scale ) );
1204 size_metrics->height = FT_PIX_ROUND(
1205 FT_MulFix( face->root.height,
1206 size_metrics->y_scale ) );
1224 FT_LOCAL_DEF( FT_Error )
1225 tt_size_reset( TT_Size size )
1227 TT_Face face = (TT_Face)size->root.face;
1228 FT_Size_Metrics* size_metrics = &size->hinted_metrics;
1232 size->ttmetrics.ppem = 0;
1234 if ( size->root.metrics.x_ppem == 0 || size->root.metrics.y_ppem == 0 )
1235 return FT_THROW( Invalid_PPem );
1238 *size_metrics = size->root.metrics;
1240 tt_size_reset_height( (FT_Size)size );
1242 if ( face->header.Flags & 8 )
1246 size_metrics->x_scale = FT_DivFix( size_metrics->x_ppem << 6,
1247 face->root.units_per_EM );
1248 size_metrics->y_scale = FT_DivFix( size_metrics->y_ppem << 6,
1249 face->root.units_per_EM );
1251 size_metrics->max_advance = FT_PIX_ROUND(
1252 FT_MulFix( face->root.max_advance_width,
1253 size_metrics->x_scale ) );
1257 if ( size_metrics->x_ppem >= size_metrics->y_ppem )
1259 size->ttmetrics.scale = size_metrics->x_scale;
1260 size->ttmetrics.ppem = size_metrics->x_ppem;
1261 size->ttmetrics.x_ratio = 0x10000L;
1262 size->ttmetrics.y_ratio = FT_DivFix( size_metrics->y_ppem,
1263 size_metrics->x_ppem );
1267 size->ttmetrics.scale = size_metrics->y_scale;
1268 size->ttmetrics.ppem = size_metrics->y_ppem;
1269 size->ttmetrics.x_ratio = FT_DivFix( size_metrics->x_ppem,
1270 size_metrics->y_ppem );
1271 size->ttmetrics.y_ratio = 0x10000L;
1274 size->widthp = tt_face_get_device_metrics( face, size_metrics->x_ppem, 0 );
1276 size->metrics = size_metrics;
1278#ifdef TT_USE_BYTECODE_INTERPRETER
1279 size->cvt_ready = -1;
1301 FT_LOCAL_DEF( FT_Error )
1302 tt_driver_init( FT_Module ttdriver )
1305#ifdef TT_USE_BYTECODE_INTERPRETER
1307 TT_Driver driver = (TT_Driver)ttdriver;
1309 driver->interpreter_version = TT_INTERPRETER_VERSION_35;
1310#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
1311 driver->interpreter_version = TT_INTERPRETER_VERSION_40;
1316 FT_UNUSED( ttdriver );
1336 FT_LOCAL_DEF(
void )
1337 tt_driver_done( FT_Module ttdriver )
1339 FT_UNUSED( ttdriver );
1358 FT_LOCAL_DEF( FT_Error )
1359 tt_slot_init( FT_GlyphSlot slot )
1361 return FT_GlyphLoader_CreateExtra( slot->internal->loader );