diff --git a/src/type1/t1driver.c b/src/type1/t1driver.c index 0c974be67..b137ddcf4 100644 --- a/src/type1/t1driver.c +++ b/src/type1/t1driver.c @@ -20,6 +20,7 @@ #include #include +#include #undef FT_COMPONENT #define FT_COMPONENT trace_t1driver @@ -137,6 +138,172 @@ } + /*************************************************************************/ + /* */ + /* */ + /* Get_Char_Index */ + /* */ + /* */ + /* Uses a charmap to return a given character code's glyph index. */ + /* */ + /* */ + /* charmap :: A handle to the source charmap object. */ + /* charcode :: The character code. */ + /* */ + /* */ + /* Glyph index. 0 means `undefined character code'. */ + /* */ + static + T1_UInt Get_Char_Index( FT_CharMap charmap, + T1_Long charcode ) + { + T1_Face face; + T1_UInt result = 0; + PSNames_Interface* psnames; + + face = (T1_Face)charmap->face; + psnames = (PSNames_Interface*)face->psnames; + if (psnames) + switch (charmap->encoding) + { + /********************************************************************/ + /* */ + /* Unicode encoding support */ + /* */ + case ft_encoding_unicode: + { + /* use the "psnames" module to synthetize the Unicode charmap */ + result = psnames->lookup_unicode( &face->unicode_map, + (T1_ULong)charcode ); + + /* the function returns 0xFFFF when the Unicode charcode has */ + /* no corresponding glyph.. */ + if (result == 0xFFFF) + result = 0; + goto Exit; + } + + /********************************************************************/ + /* */ + /* Custom Type 1 encoding */ + /* */ + case ft_encoding_adobe_custom: + { + T1_Encoding* encoding = &face->type1.encoding; + if (charcode >= encoding->code_first && + charcode <= encoding->code_last) + { + result = encoding->char_index[charcode]; + } + goto Exit; + } + + /********************************************************************/ + /* */ + /* Adobe Standard & Expert encoding support */ + /* */ + default: + if (charcode < 256) + { + FT_UInt code; + FT_Int n; + const char* glyph_name; + + code = psnames->adobe_std_encoding[charcode]; + if (charmap->encoding == ft_encoding_adobe_expert) + code = psnames->adobe_expert_encoding[charcode]; + + glyph_name = psnames->adobe_std_strings(code); + if (!glyph_name) break; + + for ( n = 0; n < face->type1.num_glyphs; n++ ) + { + const char* gname = face->type1.glyph_names[n]; + + if ( gname && gname[0] == glyph_name[0] && + strcmp( gname, glyph_name ) == 0 ) + { + result = n; + break; + } + } + } + } + Exit: + return result; + } + + + static + T1_Error Init_Face( FT_Stream stream, + FT_Int face_index, + T1_Face face ) + { + T1_Error error; + + error = T1_Init_Face(stream, face_index, face); + if (!error) + { + FT_Face root = &face->root; + FT_CharMap charmap = face->charmaprecs; + + /* synthetize a Unicode charmap if there is support in the "psnames" */ + /* module.. */ + if (face->psnames) + { + PSNames_Interface* psnames = (PSNames_Interface*)face->psnames; + if (psnames->unicode_value) + { + error = psnames->build_unicodes( root->memory, + face->type1.num_glyphs, + (const char**)face->type1.glyph_names, + &face->unicode_map ); + if (!error) + { + root->charmap = charmap; + charmap->face = (FT_Face)face; + charmap->encoding = ft_encoding_unicode; + charmap->platform_id = 3; + charmap->encoding_id = 1; + charmap++; + } + + /* simply clear the error in case of failure (which really) */ + /* means that out of memory or no unicode glyph names */ + error = 0; + } + } + + /* now, support either the standard, expert, or custom encodings */ + charmap->face = (FT_Face)face; + charmap->platform_id = 7; /* a new platform id for Adobe fonts ?? */ + + switch (face->type1.encoding_type) + { + case t1_encoding_standard: + charmap->encoding = ft_encoding_adobe_standard; + charmap->encoding_id = 0; + break; + + case t1_encoding_expert: + charmap->encoding = ft_encoding_adobe_expert; + charmap->encoding_id = 1; + break; + + default: + charmap->encoding = ft_encoding_adobe_custom; + charmap->encoding_id = 2; + break; + } + + root->charmaps = face->charmaps; + root->num_charmaps = charmap - face->charmaprecs + 1; + face->charmaps[0] = &face->charmaprecs[0]; + face->charmaps[1] = &face->charmaprecs[1]; + } + return error; + } + /******************************************************************/ /* */ /* FT_DriverInterface */ @@ -229,7 +396,7 @@ (FTDriver_doneDriver) T1_Done_Driver, (FTDriver_getInterface) 0, - (FTDriver_initFace) T1_Init_Face, + (FTDriver_initFace) Init_Face, (FTDriver_doneFace) T1_Done_Face, (FTDriver_getKerning) 0, @@ -242,7 +409,7 @@ (FTDriver_doneGlyphSlot) T1_Done_GlyphSlot, (FTDriver_loadGlyph) T1_Load_Glyph, - (FTDriver_getCharIndex) 0, + (FTDriver_getCharIndex) Get_Char_Index, }; diff --git a/src/type1/t1gload.c b/src/type1/t1gload.c index a6a020fe2..311145cac 100644 --- a/src/type1/t1gload.c +++ b/src/type1/t1gload.c @@ -268,7 +268,7 @@ n_base_points = cur->n_points; /* save the left bearing and width of the base character */ - /* as they will be erase by the next load.. */ + /* as they will be erased by the next load.. */ left_bearing = decoder->builder.left_bearing; advance = decoder->builder.advance; diff --git a/src/type1/t1objs.c b/src/type1/t1objs.c index 95be0552e..fff4bf71c 100644 --- a/src/type1/t1objs.c +++ b/src/type1/t1objs.c @@ -25,6 +25,8 @@ #include #endif +#include + /* Required by tracing mode */ #undef FT_COMPONENT #define FT_COMPONENT trace_t1objs @@ -182,14 +184,27 @@ FT_Int face_index, T1_Face face ) { - T1_Tokenizer tokenizer; - T1_Error error; + T1_Tokenizer tokenizer; + T1_Error error; + PSNames_Interface* psnames; (void)face_index; (void)face; face->root.num_faces = 1; + psnames = (PSNames_Interface*)face->psnames; + if (!psnames) + { + /* look-up the PSNames driver */ + FT_Driver psnames_driver; + + psnames_driver = FT_Get_Driver( face->root.driver->library, "psnames" ); + if (psnames_driver) + face->psnames = (PSNames_Interface*) + (psnames_driver->interface.format_interface); + } + /* open the tokenizer, this will also check the font format */ error = New_Tokenizer( stream, &tokenizer ); if (error) goto Fail;