summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/freetype/src/truetype/ttobjs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/freetype/src/truetype/ttobjs.c')
-rw-r--r--src/3rdparty/freetype/src/truetype/ttobjs.c545
1 files changed, 464 insertions, 81 deletions
diff --git a/src/3rdparty/freetype/src/truetype/ttobjs.c b/src/3rdparty/freetype/src/truetype/ttobjs.c
index 11d662d2d4..4707dfe159 100644
--- a/src/3rdparty/freetype/src/truetype/ttobjs.c
+++ b/src/3rdparty/freetype/src/truetype/ttobjs.c
@@ -4,7 +4,7 @@
/* */
/* Objects manager (body). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
+/* Copyright 1996-2013 */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -21,6 +21,7 @@
#include FT_INTERNAL_STREAM_H
#include FT_TRUETYPE_TAGS_H
#include FT_INTERNAL_SFNT_H
+#include FT_TRUETYPE_DRIVER_H
#include "ttgload.h"
#include "ttpload.h"
@@ -146,28 +147,29 @@
/* This list shall be expanded as we find more of them. */
static FT_Bool
- tt_check_trickyness( FT_String* name )
+ tt_check_trickyness_family( FT_String* name )
{
-#define TRICK_NAMES_MAX_CHARACTERS 16
-#define TRICK_NAMES_COUNT 7
- static const char trick_names[TRICK_NAMES_COUNT][TRICK_NAMES_MAX_CHARACTERS+1] =
+
+#define TRICK_NAMES_MAX_CHARACTERS 19
+#define TRICK_NAMES_COUNT 9
+
+ static const char trick_names[TRICK_NAMES_COUNT]
+ [TRICK_NAMES_MAX_CHARACTERS + 1] =
{
- "DFKaiSho-SB", /* dfkaisb.ttf */
+ "DFKaiSho-SB", /* dfkaisb.ttf */
"DFKaiShu",
- "DFKai-SB", /* kaiu.ttf */
- "HuaTianSongTi?", /* htst3.ttf */
- "MingLiU", /* mingliu.ttf & mingliu.ttc */
- "PMingLiU", /* mingliu.ttc */
- "MingLi43", /* mingli.ttf */
+ "DFKai-SB", /* kaiu.ttf */
+ "HuaTianKaiTi?", /* htkt2.ttf */
+ "HuaTianSongTi?", /* htst3.ttf */
+ "Ming(for ISO10646)", /* hkscsiic.ttf & iicore.ttf */
+ "MingLiU", /* mingliu.ttf & mingliu.ttc */
+ "PMingLiU", /* mingliu.ttc */
+ "MingLi43", /* mingli.ttf */
};
- int nn;
+ int nn;
- if ( !name )
- return FALSE;
- /* Note that we only check the face name at the moment; it might */
- /* be worth to do more checks for a few special cases. */
for ( nn = 0; nn < TRICK_NAMES_COUNT; nn++ )
if ( ft_strstr( name, trick_names[nn] ) )
return TRUE;
@@ -176,6 +178,307 @@
}
+ /* XXX: This function should be in the `sfnt' module. */
+
+ /* Some PDF generators clear the checksums in the TrueType header table. */
+ /* For example, Quartz ContextPDF clears all entries, or Bullzip PDF */
+ /* Printer clears the entries for subsetted subtables. We thus have to */
+ /* recalculate the checksums where necessary. */
+
+ static FT_UInt32
+ tt_synth_sfnt_checksum( FT_Stream stream,
+ FT_ULong length )
+ {
+ FT_Error error;
+ FT_UInt32 checksum = 0;
+ int i;
+
+
+ if ( FT_FRAME_ENTER( length ) )
+ return 0;
+
+ for ( ; length > 3; length -= 4 )
+ checksum += (FT_UInt32)FT_GET_ULONG();
+
+ for ( i = 3; length > 0; length --, i-- )
+ checksum += (FT_UInt32)( FT_GET_BYTE() << ( i * 8 ) );
+
+ FT_FRAME_EXIT();
+
+ return checksum;
+ }
+
+
+ /* XXX: This function should be in the `sfnt' module. */
+
+ static FT_ULong
+ tt_get_sfnt_checksum( TT_Face face,
+ FT_UShort i )
+ {
+#if 0 /* if we believe the written value, use following part. */
+ if ( face->dir_tables[i].CheckSum )
+ return face->dir_tables[i].CheckSum;
+#endif
+
+ if ( !face->goto_table )
+ return 0;
+
+ if ( face->goto_table( face,
+ face->dir_tables[i].Tag,
+ face->root.stream,
+ NULL ) )
+ return 0;
+
+ return (FT_ULong)tt_synth_sfnt_checksum( face->root.stream,
+ face->dir_tables[i].Length );
+ }
+
+
+ typedef struct tt_sfnt_id_rec_
+ {
+ FT_ULong CheckSum;
+ FT_ULong Length;
+
+ } tt_sfnt_id_rec;
+
+
+ static FT_Bool
+ tt_check_trickyness_sfnt_ids( TT_Face face )
+ {
+#define TRICK_SFNT_IDS_PER_FACE 3
+#define TRICK_SFNT_IDS_NUM_FACES 17
+
+ static const tt_sfnt_id_rec sfnt_id[TRICK_SFNT_IDS_NUM_FACES]
+ [TRICK_SFNT_IDS_PER_FACE] = {
+
+#define TRICK_SFNT_ID_cvt 0
+#define TRICK_SFNT_ID_fpgm 1
+#define TRICK_SFNT_ID_prep 2
+
+ { /* MingLiU 1995 */
+ { 0x05BCF058UL, 0x000002E4UL }, /* cvt */
+ { 0x28233BF1UL, 0x000087C4UL }, /* fpgm */
+ { 0xA344A1EAUL, 0x000001E1UL } /* prep */
+ },
+ { /* MingLiU 1996- */
+ { 0x05BCF058UL, 0x000002E4UL }, /* cvt */
+ { 0x28233BF1UL, 0x000087C4UL }, /* fpgm */
+ { 0xA344A1EBUL, 0x000001E1UL } /* prep */
+ },
+ { /* DFKaiShu */
+ { 0x11E5EAD4UL, 0x00000350UL }, /* cvt */
+ { 0x5A30CA3BUL, 0x00009063UL }, /* fpgm */
+ { 0x13A42602UL, 0x0000007EUL } /* prep */
+ },
+ { /* HuaTianKaiTi */
+ { 0xFFFBFFFCUL, 0x00000008UL }, /* cvt */
+ { 0x9C9E48B8UL, 0x0000BEA2UL }, /* fpgm */
+ { 0x70020112UL, 0x00000008UL } /* prep */
+ },
+ { /* HuaTianSongTi */
+ { 0xFFFBFFFCUL, 0x00000008UL }, /* cvt */
+ { 0x0A5A0483UL, 0x00017C39UL }, /* fpgm */
+ { 0x70020112UL, 0x00000008UL } /* prep */
+ },
+ { /* NEC fadpop7.ttf */
+ { 0x00000000UL, 0x00000000UL }, /* cvt */
+ { 0x40C92555UL, 0x000000E5UL }, /* fpgm */
+ { 0xA39B58E3UL, 0x0000117CUL } /* prep */
+ },
+ { /* NEC fadrei5.ttf */
+ { 0x00000000UL, 0x00000000UL }, /* cvt */
+ { 0x33C41652UL, 0x000000E5UL }, /* fpgm */
+ { 0x26D6C52AUL, 0x00000F6AUL } /* prep */
+ },
+ { /* NEC fangot7.ttf */
+ { 0x00000000UL, 0x00000000UL }, /* cvt */
+ { 0x6DB1651DUL, 0x0000019DUL }, /* fpgm */
+ { 0x6C6E4B03UL, 0x00002492UL } /* prep */
+ },
+ { /* NEC fangyo5.ttf */
+ { 0x00000000UL, 0x00000000UL }, /* cvt */
+ { 0x40C92555UL, 0x000000E5UL }, /* fpgm */
+ { 0xDE51FAD0UL, 0x0000117CUL } /* prep */
+ },
+ { /* NEC fankyo5.ttf */
+ { 0x00000000UL, 0x00000000UL }, /* cvt */
+ { 0x85E47664UL, 0x000000E5UL }, /* fpgm */
+ { 0xA6C62831UL, 0x00001CAAUL } /* prep */
+ },
+ { /* NEC fanrgo5.ttf */
+ { 0x00000000UL, 0x00000000UL }, /* cvt */
+ { 0x2D891CFDUL, 0x0000019DUL }, /* fpgm */
+ { 0xA0604633UL, 0x00001DE8UL } /* prep */
+ },
+ { /* NEC fangot5.ttc */
+ { 0x00000000UL, 0x00000000UL }, /* cvt */
+ { 0x40AA774CUL, 0x000001CBUL }, /* fpgm */
+ { 0x9B5CAA96UL, 0x00001F9AUL } /* prep */
+ },
+ { /* NEC fanmin3.ttc */
+ { 0x00000000UL, 0x00000000UL }, /* cvt */
+ { 0x0D3DE9CBUL, 0x00000141UL }, /* fpgm */
+ { 0xD4127766UL, 0x00002280UL } /* prep */
+ },
+ { /* NEC FA-Gothic, 1996 */
+ { 0x00000000UL, 0x00000000UL }, /* cvt */
+ { 0x4A692698UL, 0x000001F0UL }, /* fpgm */
+ { 0x340D4346UL, 0x00001FCAUL } /* prep */
+ },
+ { /* NEC FA-Minchou, 1996 */
+ { 0x00000000UL, 0x00000000UL }, /* cvt */
+ { 0xCD34C604UL, 0x00000166UL }, /* fpgm */
+ { 0x6CF31046UL, 0x000022B0UL } /* prep */
+ },
+ { /* NEC FA-RoundGothicB, 1996 */
+ { 0x00000000UL, 0x00000000UL }, /* cvt */
+ { 0x5DA75315UL, 0x0000019DUL }, /* fpgm */
+ { 0x40745A5FUL, 0x000022E0UL } /* prep */
+ },
+ { /* NEC FA-RoundGothicM, 1996 */
+ { 0x00000000UL, 0x00000000UL }, /* cvt */
+ { 0xF055FC48UL, 0x000001C2UL }, /* fpgm */
+ { 0x3900DED3UL, 0x00001E18UL } /* prep */
+ }
+ };
+
+ FT_ULong checksum;
+ int num_matched_ids[TRICK_SFNT_IDS_NUM_FACES];
+ FT_Bool has_cvt, has_fpgm, has_prep;
+ FT_UShort i;
+ int j, k;
+
+
+ FT_MEM_SET( num_matched_ids, 0,
+ sizeof ( int ) * TRICK_SFNT_IDS_NUM_FACES );
+ has_cvt = FALSE;
+ has_fpgm = FALSE;
+ has_prep = FALSE;
+
+ for ( i = 0; i < face->num_tables; i++ )
+ {
+ checksum = 0;
+
+ switch( face->dir_tables[i].Tag )
+ {
+ case TTAG_cvt:
+ k = TRICK_SFNT_ID_cvt;
+ has_cvt = TRUE;
+ break;
+
+ case TTAG_fpgm:
+ k = TRICK_SFNT_ID_fpgm;
+ has_fpgm = TRUE;
+ break;
+
+ case TTAG_prep:
+ k = TRICK_SFNT_ID_prep;
+ has_prep = TRUE;
+ break;
+
+ default:
+ continue;
+ }
+
+ for ( j = 0; j < TRICK_SFNT_IDS_NUM_FACES; j++ )
+ if ( face->dir_tables[i].Length == sfnt_id[j][k].Length )
+ {
+ if ( !checksum )
+ checksum = tt_get_sfnt_checksum( face, i );
+
+ if ( sfnt_id[j][k].CheckSum == checksum )
+ num_matched_ids[j]++;
+
+ if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE )
+ return TRUE;
+ }
+ }
+
+ for ( j = 0; j < TRICK_SFNT_IDS_NUM_FACES; j++ )
+ {
+ if ( !has_cvt && !sfnt_id[j][TRICK_SFNT_ID_cvt].Length )
+ num_matched_ids[j] ++;
+ if ( !has_fpgm && !sfnt_id[j][TRICK_SFNT_ID_fpgm].Length )
+ num_matched_ids[j] ++;
+ if ( !has_prep && !sfnt_id[j][TRICK_SFNT_ID_prep].Length )
+ num_matched_ids[j] ++;
+ if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE )
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+
+
+ static FT_Bool
+ tt_check_trickyness( FT_Face face )
+ {
+ if ( !face )
+ return FALSE;
+
+ /* For first, check the face name for quick check. */
+ if ( face->family_name &&
+ tt_check_trickyness_family( face->family_name ) )
+ return TRUE;
+
+ /* Type42 fonts may lack `name' tables, we thus try to identify */
+ /* tricky fonts by checking the checksums of Type42-persistent */
+ /* sfnt tables (`cvt', `fpgm', and `prep'). */
+ if ( tt_check_trickyness_sfnt_ids( (TT_Face)face ) )
+ return TRUE;
+
+ return FALSE;
+ }
+
+
+ /* Check whether `.notdef' is the only glyph in the `loca' table. */
+ static FT_Bool
+ tt_check_single_notdef( FT_Face ttface )
+ {
+ FT_Bool result = FALSE;
+
+ TT_Face face = (TT_Face)ttface;
+ FT_UInt asize;
+ FT_ULong i;
+ FT_ULong glyph_index = 0;
+ FT_UInt count = 0;
+
+
+ for( i = 0; i < face->num_locations; i++ )
+ {
+ tt_face_get_location( face, i, &asize );
+ if ( asize > 0 )
+ {
+ count += 1;
+ if ( count > 1 )
+ break;
+ glyph_index = i;
+ }
+ }
+
+ /* Only have a single outline. */
+ if ( count == 1 )
+ {
+ if ( glyph_index == 0 )
+ result = TRUE;
+ else
+ {
+ /* FIXME: Need to test glyphname == .notdef ? */
+ FT_Error error;
+ char buf[8];
+
+
+ error = FT_Get_Glyph_Name( ttface, glyph_index, buf, 8 );
+ if ( !error &&
+ buf[0] == '.' && !ft_strncmp( buf, ".notdef", 8 ) )
+ result = TRUE;
+ }
+ }
+
+ return result;
+ }
+
+
/*************************************************************************/
/* */
/* <Function> */
@@ -212,10 +515,17 @@
TT_Face face = (TT_Face)ttface;
+ FT_TRACE2(( "TTF driver\n" ));
+
library = ttface->driver->root.library;
- sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" );
+
+ sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" );
if ( !sfnt )
- goto Bad_Format;
+ {
+ FT_ERROR(( "tt_face_init: cannot access `sfnt' module\n" ));
+ error = FT_THROW( Missing_Module );
+ goto Exit;
+ }
/* create input stream from resource */
if ( FT_STREAM_SEEK( 0 ) )
@@ -223,6 +533,10 @@
/* check that we have a valid TrueType file */
error = sfnt->init_face( stream, face, face_index, num_params, params );
+
+ /* Stream may have changed. */
+ stream = face->root.stream;
+
if ( error )
goto Exit;
@@ -233,7 +547,7 @@
face->format_tag != 0x00020000L && /* CJK fonts for Win 3.1 */
face->format_tag != TTAG_true ) /* Mac fonts */
{
- FT_TRACE2(( "[not a valid TTF font]\n" ));
+ FT_TRACE2(( " not a TTF font\n" ));
goto Bad_Format;
}
@@ -243,14 +557,14 @@
/* If we are performing a simple font format check, exit immediately. */
if ( face_index < 0 )
- return TT_Err_Ok;
+ return FT_Err_Ok;
/* Load font directory */
error = sfnt->load_face( stream, face, face_index, num_params, params );
if ( error )
goto Exit;
- if ( tt_check_trickyness( ttface->family_name ) )
+ if ( tt_check_trickyness( ttface ) )
ttface->face_flags |= FT_FACE_FLAG_TRICKY;
error = tt_face_load_hdmx( face, stream );
@@ -271,6 +585,20 @@
if ( !error )
error = tt_face_load_prep( face, stream );
+ /* Check the scalable flag based on `loca'. */
+ if ( !ttface->internal->incremental_interface &&
+ ttface->num_fixed_sizes &&
+ face->glyph_locations &&
+ tt_check_single_notdef( ttface ) )
+ {
+ FT_TRACE5(( "tt_face_init:"
+ " Only the `.notdef' glyph has an outline.\n"
+ " "
+ " Resetting scalable flag to FALSE.\n" ));
+
+ ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE;
+ }
+
#else
if ( !error )
@@ -282,6 +610,19 @@
if ( !error )
error = tt_face_load_prep( face, stream );
+ /* Check the scalable flag based on `loca'. */
+ if ( ttface->num_fixed_sizes &&
+ face->glyph_locations &&
+ tt_check_single_notdef( ttface ) )
+ {
+ FT_TRACE5(( "tt_face_init:"
+ " Only the `.notdef' glyph has an outline.\n"
+ " "
+ " Resetting scalable flag to FALSE.\n" ));
+
+ ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE;
+ }
+
#endif
}
@@ -316,7 +657,7 @@
return error;
Bad_Format:
- error = TT_Err_Unknown_File_Format;
+ error = FT_THROW( Unknown_File_Format );
goto Exit;
}
@@ -394,13 +735,16 @@
/* Run the font program. */
/* */
/* <Input> */
- /* size :: A handle to the size object. */
+ /* size :: A handle to the size object. */
+ /* */
+ /* pedantic :: Set if bytecode execution should be pedantic. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
FT_LOCAL_DEF( FT_Error )
- tt_size_run_fpgm( TT_Size size )
+ tt_size_run_fpgm( TT_Size size,
+ FT_Bool pedantic )
{
TT_Face face = (TT_Face)size->root.face;
TT_ExecContext exec;
@@ -414,19 +758,23 @@
exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
if ( !exec )
- return TT_Err_Could_Not_Find_Context;
+ return FT_THROW( Could_Not_Find_Context );
- TT_Load_Context( exec, face, size );
+ error = TT_Load_Context( exec, face, size );
+ if ( error )
+ return error;
- exec->callTop = 0;
- exec->top = 0;
+ exec->callTop = 0;
+ exec->top = 0;
exec->period = 64;
exec->phase = 0;
exec->threshold = 0;
exec->instruction_trap = FALSE;
- exec->F_dot_P = 0x10000L;
+ exec->F_dot_P = 0x4000L;
+
+ exec->pedantic_hinting = pedantic;
{
FT_Size_Metrics* metrics = &exec->metrics;
@@ -455,13 +803,15 @@
if ( face->font_program_size > 0 )
{
- error = TT_Goto_CodeRange( exec, tt_coderange_font, 0 );
+ TT_Goto_CodeRange( exec, tt_coderange_font, 0 );
- if ( !error )
- error = face->interpreter( exec );
+ FT_TRACE4(( "Executing `fpgm' table.\n" ));
+ error = face->interpreter( exec );
}
else
- error = TT_Err_Ok;
+ error = FT_Err_Ok;
+
+ size->bytecode_ready = error;
if ( !error )
TT_Save_Context( exec, size );
@@ -479,13 +829,16 @@
/* Run the control value program. */
/* */
/* <Input> */
- /* size :: A handle to the size object. */
+ /* size :: A handle to the size object. */
+ /* */
+ /* pedantic :: Set if bytecode execution should be pedantic. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
FT_LOCAL_DEF( FT_Error )
- tt_size_run_prep( TT_Size size )
+ tt_size_run_prep( TT_Size size,
+ FT_Bool pedantic )
{
TT_Face face = (TT_Face)size->root.face;
TT_ExecContext exec;
@@ -499,15 +852,19 @@
exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
if ( !exec )
- return TT_Err_Could_Not_Find_Context;
+ return FT_THROW( Could_Not_Find_Context );
- TT_Load_Context( exec, face, size );
+ error = TT_Load_Context( exec, face, size );
+ if ( error )
+ return error;
exec->callTop = 0;
exec->top = 0;
exec->instruction_trap = FALSE;
+ exec->pedantic_hinting = pedantic;
+
TT_Set_CodeRange( exec,
tt_coderange_cvt,
face->cvt_program,
@@ -517,13 +874,39 @@
if ( face->cvt_program_size > 0 )
{
- error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
+ TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
+
+ if ( !size->debug )
+ {
+ FT_TRACE4(( "Executing `prep' table.\n" ));
- if ( !error && !size->debug )
error = face->interpreter( exec );
+ }
}
else
- error = TT_Err_Ok;
+ error = FT_Err_Ok;
+
+ size->cvt_ready = error;
+
+ /* UNDOCUMENTED! The MS rasterizer doesn't allow the following */
+ /* graphics state variables to be modified by the CVT program. */
+
+ exec->GS.dualVector.x = 0x4000;
+ exec->GS.dualVector.y = 0;
+ exec->GS.projVector.x = 0x4000;
+ exec->GS.projVector.y = 0x0;
+ exec->GS.freeVector.x = 0x4000;
+ exec->GS.freeVector.y = 0x0;
+
+ exec->GS.rp0 = 0;
+ exec->GS.rp1 = 0;
+ exec->GS.rp2 = 0;
+
+ exec->GS.gep0 = 1;
+ exec->GS.gep1 = 1;
+ exec->GS.gep2 = 1;
+
+ exec->GS.loop = 1;
/* save as default graphics state */
size->GS = exec->GS;
@@ -533,10 +916,6 @@
return error;
}
-#endif /* TT_USE_BYTECODE_INTERPRETER */
-
-
-#ifdef TT_USE_BYTECODE_INTERPRETER
static void
tt_size_done_bytecode( FT_Size ftsize )
@@ -574,28 +953,28 @@
size->max_func = 0;
size->max_ins = 0;
- size->bytecode_ready = 0;
- size->cvt_ready = 0;
+ size->bytecode_ready = -1;
+ size->cvt_ready = -1;
}
/* Initialize bytecode-related fields in the size object. */
/* We do this only if bytecode interpretation is really needed. */
static FT_Error
- tt_size_init_bytecode( FT_Size ftsize )
+ tt_size_init_bytecode( FT_Size ftsize,
+ FT_Bool pedantic )
{
FT_Error error;
TT_Size size = (TT_Size)ftsize;
TT_Face face = (TT_Face)ftsize->face;
FT_Memory memory = face->root.memory;
- FT_Int i;
FT_UShort n_twilight;
TT_MaxProfile* maxp = &face->max_profile;
- size->bytecode_ready = 1;
- size->cvt_ready = 0;
+ size->bytecode_ready = -1;
+ size->cvt_ready = -1;
size->max_function_defs = maxp->maxFunctionDefs;
size->max_instruction_defs = maxp->maxInstructionDefs;
@@ -617,9 +996,11 @@
metrics->rotated = FALSE;
metrics->stretched = FALSE;
- /* set default compensation (all 0) */
- for ( i = 0; i < 4; i++ )
- metrics->compensations[i] = 0;
+ /* set default engine compensation */
+ metrics->compensations[0] = 0; /* gray */
+ metrics->compensations[1] = 0; /* black */
+ metrics->compensations[2] = 0; /* white */
+ metrics->compensations[3] = 0; /* reserved */
}
/* allocate function defs, instruction defs, cvt, and storage area */
@@ -655,7 +1036,7 @@
}
/* Fine, now run the font program! */
- error = tt_size_run_fpgm( size );
+ error = tt_size_run_fpgm( size, pedantic );
Exit:
if ( error )
@@ -666,20 +1047,20 @@
FT_LOCAL_DEF( FT_Error )
- tt_size_ready_bytecode( TT_Size size )
+ tt_size_ready_bytecode( TT_Size size,
+ FT_Bool pedantic )
{
- FT_Error error = TT_Err_Ok;
+ FT_Error error = FT_Err_Ok;
- if ( !size->bytecode_ready )
- {
- error = tt_size_init_bytecode( (FT_Size)size );
- if ( error )
- goto Exit;
- }
+ if ( size->bytecode_ready < 0 )
+ error = tt_size_init_bytecode( (FT_Size)size, pedantic );
+
+ if ( error || size->bytecode_ready )
+ goto Exit;
/* rescale CVT when needed */
- if ( !size->cvt_ready )
+ if ( size->cvt_ready < 0 )
{
FT_UInt i;
TT_Face face = (TT_Face)size->root.face;
@@ -705,9 +1086,7 @@
size->GS = tt_default_graphics_state;
- error = tt_size_run_prep( size );
- if ( !error )
- size->cvt_ready = 1;
+ error = tt_size_run_prep( size, pedantic );
}
Exit:
@@ -735,11 +1114,12 @@
tt_size_init( FT_Size ttsize ) /* TT_Size */
{
TT_Size size = (TT_Size)ttsize;
- FT_Error error = TT_Err_Ok;
+ FT_Error error = FT_Err_Ok;
+
#ifdef TT_USE_BYTECODE_INTERPRETER
- size->bytecode_ready = 0;
- size->cvt_ready = 0;
+ size->bytecode_ready = -1;
+ size->cvt_ready = -1;
#endif
size->ttmetrics.valid = FALSE;
@@ -767,8 +1147,7 @@
#ifdef TT_USE_BYTECODE_INTERPRETER
- if ( size->bytecode_ready )
- tt_size_done_bytecode( ttsize );
+ tt_size_done_bytecode( ttsize );
#endif
size->ttmetrics.valid = FALSE;
@@ -791,7 +1170,7 @@
tt_size_reset( TT_Size size )
{
TT_Face face;
- FT_Error error = TT_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_Size_Metrics* metrics;
@@ -805,7 +1184,7 @@
*metrics = size->root.metrics;
if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 )
- return TT_Err_Invalid_PPem;
+ return FT_THROW( Invalid_PPem );
/* This bit flag, if set, indicates that the ppems must be */
/* rounded to integers. Nearly all TrueType fonts have this bit */
@@ -835,22 +1214,20 @@
size->ttmetrics.scale = metrics->x_scale;
size->ttmetrics.ppem = metrics->x_ppem;
size->ttmetrics.x_ratio = 0x10000L;
- size->ttmetrics.y_ratio = FT_MulDiv( metrics->y_ppem,
- 0x10000L,
+ size->ttmetrics.y_ratio = FT_DivFix( metrics->y_ppem,
metrics->x_ppem );
}
else
{
size->ttmetrics.scale = metrics->y_scale;
size->ttmetrics.ppem = metrics->y_ppem;
- size->ttmetrics.x_ratio = FT_MulDiv( metrics->x_ppem,
- 0x10000L,
+ size->ttmetrics.x_ratio = FT_DivFix( metrics->x_ppem,
metrics->y_ppem );
size->ttmetrics.y_ratio = 0x10000L;
}
#ifdef TT_USE_BYTECODE_INTERPRETER
- size->cvt_ready = 0;
+ size->cvt_ready = -1;
#endif /* TT_USE_BYTECODE_INTERPRETER */
if ( !error )
@@ -884,15 +1261,21 @@
if ( !TT_New_Context( driver ) )
- return TT_Err_Could_Not_Find_Context;
+ return FT_THROW( Could_Not_Find_Context );
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+ driver->interpreter_version = TT_INTERPRETER_VERSION_38;
#else
+ driver->interpreter_version = TT_INTERPRETER_VERSION_35;
+#endif
+
+#else /* !TT_USE_BYTECODE_INTERPRETER */
FT_UNUSED( ttdriver );
-#endif
+#endif /* !TT_USE_BYTECODE_INTERPRETER */
- return TT_Err_Ok;
+ return FT_Err_Ok;
}