diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/truetype/ttobjs.c | 67 |
1 files changed, 46 insertions, 21 deletions
diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c index 906406db..8fe86ad1 100644 --- a/src/truetype/ttobjs.c +++ b/src/truetype/ttobjs.c @@ -149,9 +149,12 @@ static FT_Bool tt_check_trickyness_family( FT_String* name ) { + #define TRICK_NAMES_MAX_CHARACTERS 16 -#define TRICK_NAMES_COUNT 8 - static const char trick_names[TRICK_NAMES_COUNT][TRICK_NAMES_MAX_CHARACTERS+1] = +#define TRICK_NAMES_COUNT 8 + + static const char trick_names[TRICK_NAMES_COUNT] + [TRICK_NAMES_MAX_CHARACTERS + 1] = { "DFKaiSho-SB", /* dfkaisb.ttf */ "DFKaiShu", @@ -162,7 +165,10 @@ "PMingLiU", /* mingliu.ttc */ "MingLi43", /* mingli.ttf */ }; + int nn; + + for ( nn = 0; nn < TRICK_NAMES_COUNT; nn++ ) if ( ft_strstr( name, trick_names[nn] ) ) return TRUE; @@ -171,11 +177,13 @@ } - /* XXX: this function should be in sfnt module */ - /* some PDF generators clear the checksum in TrueType header */ - /* (Quartz ContextPDF clears all, Bullzip PDF Printer clears */ - /* for the subsetted subtables), we have to recalculate when */ - /* it is cleared. */ + /* 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 ) @@ -200,15 +208,18 @@ } - /* XXX: this function should be in sfnt module */ + /* XXX: This function should be in the `sfnt' module. */ + static FT_ULong tt_get_sfnt_checksum( TT_Face face, FT_UShort i ) { if ( face->dir_tables[i].CheckSum ) return face->dir_tables[i].CheckSum; + else if ( !face->goto_table ) return 0; + else if ( !face->goto_table( face, face->dir_tables[i].Tag, face->root.stream, @@ -216,7 +227,7 @@ return 0; return (FT_ULong)tt_synth_sfnt_checksum( face->root.stream, - face->dir_tables[i].Length ); + face->dir_tables[i].Length ); } @@ -224,19 +235,23 @@ { 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 5 +#define TRICK_SFNT_IDS_PER_FACE 3 +#define TRICK_SFNT_IDS_NUM_FACES 5 + 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 + +#define TRICK_SFNT_ID_cvt 0 +#define TRICK_SFNT_ID_fpgm 1 +#define TRICK_SFNT_ID_prep 2 + { /* MingLiU 1995 */ { 0x05bcf058, 0x000002e4 }, /* cvt */ { 0x28233bf1, 0x000087c4 }, /* fpgm */ @@ -263,36 +278,46 @@ { 0x70020112, 0x00000008 } /* prep */ } }; + FT_ULong checksum; int num_matched_ids[TRICK_SFNT_IDS_NUM_FACES]; int i, j, k; - FT_MEM_SET( num_matched_ids, 0, sizeof( int ) * TRICK_SFNT_IDS_NUM_FACES ); + + FT_MEM_SET( num_matched_ids, 0, + sizeof( int ) * TRICK_SFNT_IDS_NUM_FACES ); for ( i = 0; i < face->num_tables; i++ ) { checksum = 0; + switch( face->dir_tables[i].Tag ) { case TTAG_cvt: k = TRICK_SFNT_ID_cvt; break; + case TTAG_fpgm: k = TRICK_SFNT_ID_fpgm; break; + case TTAG_prep: k = TRICK_SFNT_ID_prep; 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] ++; + num_matched_ids[j]++; + if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE ) return TRUE; } @@ -308,8 +333,7 @@ if ( !face ) 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. */ + /* First, check the face name. */ if ( face->family_name ) { if ( tt_check_trickyness_family( face->family_name ) ) @@ -318,9 +342,10 @@ return FALSE; } - /* Type42 may lack `name' tables, try to identfiy tricky fonts by */ - /* the checksums of Type42-persistent sfnt tables; cvt, fpgm, prep */ - if ( tt_check_trickyness_sfnt_ids( ( TT_Face )face ) ) + /* 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; |