diff options
author | Werner Lemberg <wl@gnu.org> | 2002-02-04 20:55:58 +0000 |
---|---|---|
committer | Werner Lemberg <wl@gnu.org> | 2002-02-04 20:55:58 +0000 |
commit | 0f7c2f1aa58c2251d6c1a3f388a50bfa97cb097f (patch) | |
tree | 7fb4c60ca8ca8dc4bde0661b7e490210555a122d /src | |
parent | 3604d5f5581bdf39d990dcc9b0e21a828dd0f24a (diff) |
Adding the function `FT_Get_Next_Char', doing the obvious thing
w.r.t. the selected charmap.
* include/freetype/freetype.h: Add prototype.
* include/freetype/internal/ftdriver.h: Add `FTDriver_getNextChar'
typedef.
(FT_Driver_Class): Use it.
* include/freetype/internal/psnames.h: Add `PS_Next_Unicode_Func'
typedef.
(PSNames_Interface): Use it.
* include/freetype/internal/tttypes.h: Add `TT_CharNext_Func'
typedef.
(TT_CMapTable): Use it.
* src/base/ftobjs.c (FT_Get_Next_Char): New function, implementing
high-level API.
* src/cff/cffdrivr.c (cff_get_next_char): New function.
(cff_driver_class): Add it.
* src/cid/cidriver.c (Cid_Get_Next_Char): New function.
(t1cid_driver_class): Add it.
* src/pcf/pcfdriver.c (PCF_Get_Next_Char): New function.
(pcf_driver_class): Add it.
* src/psnames/psmodule.c (PS_Next_Unicode): New function.
(psnames_interface): Add it.
* src/sfnt/ttcmap.c (code_to_next0, code_to_next2, code_to_next4,
code_to_next6, code_to_next_8_12, code_to_next_10): New auxiliary
functions.
(TT_CharMap_Load): Use them.
* src/truetype/ttdriver.c (Get_Next_Char): New function.
(tt_driver_class): Add it.
* src/type1/t1driver.c (Get_Next_Char): New function.
(t1_driver_class): Add it.
* src/winfnt/winfnt.c (FNT_Get_Next_Char): New function.
(winfnt_driver_class): Add it.
* src/pcf/pcfread.c (pcf_load_font): For now, report Unicode for
Unicode and Latin 1 encodings.
Diffstat (limited to 'src')
-rw-r--r-- | src/base/ftobjs.c | 19 | ||||
-rw-r--r-- | src/cff/cffdrivr.c | 48 | ||||
-rw-r--r-- | src/cid/cidriver.c | 102 | ||||
-rw-r--r-- | src/pcf/pcfdriver.c | 44 | ||||
-rw-r--r-- | src/pcf/pcfread.c | 25 | ||||
-rw-r--r-- | src/psnames/psmodule.c | 52 | ||||
-rw-r--r-- | src/sfnt/ttcmap.c | 343 | ||||
-rw-r--r-- | src/truetype/ttdriver.c | 51 | ||||
-rw-r--r-- | src/type1/t1driver.c | 98 | ||||
-rw-r--r-- | src/winfonts/winfnt.c | 25 |
10 files changed, 786 insertions, 21 deletions
diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index f2eb2794..21a6be0f 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -1867,6 +1867,25 @@ return result; } + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_ULong ) + FT_Get_Next_Char( FT_Face face, + FT_ULong charcode ) + { + FT_ULong result; + FT_Driver driver; + + + result = 0; + if ( face && face->charmap ) + { + driver = face->driver; + result = driver->clazz->get_next_char( face->charmap, charcode ); + } + return result; + } + /* documentation is in freetype.h */ diff --git a/src/cff/cffdrivr.c b/src/cff/cffdrivr.c index 6b89b2af..24e4200b 100644 --- a/src/cff/cffdrivr.c +++ b/src/cff/cffdrivr.c @@ -320,6 +320,50 @@ /*************************************************************************/ /* */ /* <Function> */ + /* cff_get_next_char */ + /* */ + /* <Description> */ + /* Uses a charmap to return the next encoded charcode. */ + /* */ + /* <Input> */ + /* charmap :: A handle to the source charmap object. */ + /* charcode :: The character code. */ + /* */ + /* <Return> */ + /* Char code. 0 means `no encoded chars above the given one'. */ + /* */ + static FT_Long + cff_get_next_char( TT_CharMap charmap, + FT_Long charcode ) + { + FT_Error error; + CFF_Face face; + TT_CMapTable* cmap; + + + cmap = &charmap->cmap; + face = (CFF_Face)charmap->root.face; + + /* Load table if needed */ + if ( !cmap->loaded ) + { + SFNT_Interface* sfnt = (SFNT_Interface*)face->sfnt; + + + error = sfnt->load_charmap( face, cmap, face->root.stream ); + if ( error ) + return 0; + + cmap->loaded = TRUE; + } + + return ( cmap->get_next_char ? cmap->get_next_char( cmap, charcode ) : 0 ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ /* cff_get_name_index */ /* */ /* <Description> */ @@ -454,7 +498,9 @@ (FTDriver_getKerning) Get_Kerning, (FTDriver_attachFile) 0, - (FTDriver_getAdvances) 0 + (FTDriver_getAdvances) 0, + + (FTDriver_getNextChar) cff_get_next_char }; diff --git a/src/cid/cidriver.c b/src/cid/cidriver.c index 9edbc698..21f0594b 100644 --- a/src/cid/cidriver.c +++ b/src/cid/cidriver.c @@ -185,6 +185,104 @@ } + /*************************************************************************/ + /* */ + /* <Function> */ + /* Cid_Get_Next_Char */ + /* */ + /* <Description> */ + /* Uses a charmap to return the next encoded char after. */ + /* */ + /* <Input> */ + /* charmap :: A handle to the source charmap object. */ + /* */ + /* charcode :: The character code. */ + /* */ + /* <Return> */ + /* Next char code. 0 means `no more char codes'. */ + /* */ + static FT_Long + CID_Get_Next_Char( FT_CharMap charmap, + FT_Long charcode ) + { + T1_Face face; + 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 */ + return psnames->next_unicode (&face->unicode_map, + (FT_ULong)charcode ); + + /*******************************************************************/ + /* */ + /* Custom Type 1 encoding */ + /* */ + case ft_encoding_adobe_custom: + { + T1_Encoding* encoding = &face->type1.encoding; + + + charcode++; + if ( charcode < encoding->code_first ) + charcode = encoding->code_first; + while ( charcode <= encoding->code_last ) + { + if ( encoding->char_index[charcode] ) + return charcode; + charcode++; + } + } + break; + + /*******************************************************************/ + /* */ + /* Adobe Standard & Expert encoding support */ + /* */ + default: + while ( ++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 ) + continue; + + 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 ) + { + return charcode; + } + } + } + } + + return 0; + } + + FT_CALLBACK_TABLE_DEF const FT_Driver_Class t1cid_driver_class = { @@ -228,7 +326,9 @@ (FTDriver_getKerning) 0, (FTDriver_attachFile) 0, - (FTDriver_getAdvances) 0 + (FTDriver_getAdvances) 0, + + (FTDriver_getNextChar) CID_Get_Next_Char }; diff --git a/src/pcf/pcfdriver.c b/src/pcf/pcfdriver.c index 2b3ab49b..d172879d 100644 --- a/src/pcf/pcfdriver.c +++ b/src/pcf/pcfdriver.c @@ -276,6 +276,46 @@ THE SOFTWARE. } + static FT_Long + PCF_Get_Next_Char( FT_CharMap charmap, + FT_Long char_code ) + { + PCF_Face face = (PCF_Face)charmap->face; + PCF_Encoding en_table = face->encodings; + int low, high, mid; + + + FT_TRACE4(( "get_char_index %ld\n", char_code )); + + char_code++; + low = 0; + high = face->nencodings - 1; + + while ( low <= high ) + { + mid = ( low + high ) / 2; + if ( char_code < en_table[mid].enc ) + high = mid - 1; + else if ( char_code > en_table[mid].enc ) + low = mid + 1; + else + return char_code; + } + + if ( high < 0 ) + high = 0; + + while ( high < face->nencodings ) + { + if ( en_table[high].enc >= char_code ) + return en_table[high].enc; + high++; + } + + return 0; + } + + FT_CALLBACK_TABLE_DEF const FT_Driver_Class pcf_driver_class = { @@ -313,7 +353,9 @@ THE SOFTWARE. (FTDriver_getKerning) 0, (FTDriver_attachFile) 0, - (FTDriver_getAdvances) 0 + (FTDriver_getAdvances) 0, + + (FTDriver_getNextChar) PCF_Get_Next_Char }; diff --git a/src/pcf/pcfread.c b/src/pcf/pcfread.c index d7691260..07acee32 100644 --- a/src/pcf/pcfread.c +++ b/src/pcf/pcfread.c @@ -1021,10 +1021,14 @@ THE SOFTWARE. root->available_sizes->height = 12; } - /* XXX: charmaps */ + /* XXX: charmaps. For now, report unicode for Unicode and Latin 1 */ root->charmaps = &face->charmap_handle; root->num_charmaps = 1; + face->charmap.encoding = ft_encoding_none; + face->charmap.platform_id = 0; + face->charmap.encoding_id = 0; + { PCF_Property charset_registry = 0, charset_encoding = 0; @@ -1049,28 +1053,21 @@ THE SOFTWARE. strcpy( face->charset_registry, charset_registry->value.atom ); strcpy( face->charset_encoding, charset_encoding->value.atom ); -#if 0 - if ( !strcmp( charset_registry, "ISO10646" ) ) + if ( !strcmp( face->charset_registry, "ISO10646" ) || + ( !strcmp( face->charset_registry, "ISO8859" ) && + !strcmp( face->charset_encoding, "1" ) ) ) { face->charmap.encoding = ft_encoding_unicode; face->charmap.platform_id = 3; face->charmap.encoding_id = 1; - face->charmap.face = root; - face->charmap_handle - - return PCF_Err_Ok; } -#endif } } } - face->charmap.encoding = ft_encoding_none; - face->charmap.platform_id = 0; - face->charmap.encoding_id = 0; - face->charmap.face = root; - face->charmap_handle = &face->charmap; - root->charmap = face->charmap_handle; + face->charmap.face = root; + face->charmap_handle = &face->charmap; + root->charmap = face->charmap_handle; } return PCF_Err_Ok; diff --git a/src/psnames/psmodule.c b/src/psnames/psmodule.c index 9f6ccf59..5b3e2de4 100644 --- a/src/psnames/psmodule.c +++ b/src/psnames/psmodule.c @@ -238,6 +238,48 @@ } + static FT_ULong + PS_Next_Unicode( PS_Unicodes* table, + FT_ULong unicode ) + { + PS_UniMap *min, *max, *mid; + + + unicode++; + /* perform a binary search on the table */ + + min = table->maps; + max = min + table->num_maps - 1; + + while ( min <= max ) + { + mid = min + ( max - min ) / 2; + if ( mid->unicode == unicode ) + return unicode; + + if ( min == max ) + break; + + if ( mid->unicode < unicode ) + min = mid + 1; + else + max = mid - 1; + } + + if ( max < table->maps ) + max = table->maps; + + while ( max < table->maps + table->num_maps ) + { + if ( unicode < max->unicode ) + return max->unicode; + max++; + } + + return 0; + } + + #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ @@ -272,6 +314,7 @@ 0, 0, 0, + 0, #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ @@ -279,7 +322,14 @@ (PS_Adobe_Std_Strings_Func)PS_Standard_Strings, t1_standard_encoding, - t1_expert_encoding + t1_expert_encoding, + +#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST + (PS_Next_Unicode_Func) PS_Next_Unicode +#else + 0 +#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ + }; diff --git a/src/sfnt/ttcmap.c b/src/sfnt/ttcmap.c index b37faf4c..1a3fb17f 100644 --- a/src/sfnt/ttcmap.c +++ b/src/sfnt/ttcmap.c @@ -38,26 +38,50 @@ code_to_index0( TT_CMapTable* charmap, FT_ULong char_code ); + FT_CALLBACK_DEF( FT_ULong ) + code_to_next0( TT_CMapTable* charmap, + FT_ULong char_code ); + FT_CALLBACK_DEF( FT_UInt ) code_to_index2( TT_CMapTable* charmap, FT_ULong char_code ); + FT_CALLBACK_DEF( FT_ULong ) + code_to_next2( TT_CMapTable* charmap, + FT_ULong char_code ); + FT_CALLBACK_DEF( FT_UInt ) code_to_index4( TT_CMapTable* charmap, FT_ULong char_code ); + FT_CALLBACK_DEF( FT_ULong ) + code_to_next4( TT_CMapTable* charmap, + FT_ULong char_code ); + FT_CALLBACK_DEF( FT_UInt ) code_to_index6( TT_CMapTable* charmap, FT_ULong char_code ); + FT_CALLBACK_DEF( FT_ULong ) + code_to_next6( TT_CMapTable* charmap, + FT_ULong char_code ); + FT_CALLBACK_DEF( FT_UInt ) code_to_index8_12( TT_CMapTable* charmap, FT_ULong char_code ); + FT_CALLBACK_DEF( FT_ULong ) + code_to_next8_12( TT_CMapTable* charmap, + FT_ULong char_code ); + FT_CALLBACK_DEF( FT_UInt ) code_to_index10( TT_CMapTable* charmap, FT_ULong char_code ); + FT_CALLBACK_DEF( FT_ULong ) + code_to_next10( TT_CMapTable* charmap, + FT_ULong char_code ); + /*************************************************************************/ /* */ @@ -125,6 +149,7 @@ goto Fail; cmap->get_index = code_to_index0; + cmap->get_next_char = code_to_next0; break; case 2: @@ -196,6 +221,7 @@ FORGET_Frame(); cmap->get_index = code_to_index2; + cmap->get_next_char = code_to_next2; break; case 4: @@ -262,6 +288,7 @@ cmap4->last_segment = cmap4->segments; cmap->get_index = code_to_index4; + cmap->get_next_char = code_to_next4; break; case 6: @@ -287,6 +314,7 @@ FORGET_Frame(); cmap->get_index = code_to_index6; + cmap->get_next_char = code_to_next6; break; case 8: @@ -328,6 +356,7 @@ cmap8_12->last_group = cmap8_12->groups; cmap->get_index = code_to_index8_12; + cmap->get_next_char = code_to_next8_12; break; case 10: @@ -354,6 +383,7 @@ FORGET_Frame(); cmap->get_index = code_to_index10; + cmap->get_next_char = code_to_next10; break; default: /* corrupt character mapping table */ @@ -471,6 +501,37 @@ /*************************************************************************/ /* */ /* <Function> */ + /* code_to_next0 */ + /* */ + /* <Description> */ + /* Finds the next encoded character after the given one. Uses */ + /* format 0. `charCode' must be in the range 0x00-0xFF (otherwise 0 */ + /* is returned). */ + /* */ + /* <Input> */ + /* charCode :: The wanted character code. */ + /* cmap0 :: A pointer to a cmap table in format 0. */ + /* */ + /* <Return> */ + /* Next char code. 0 if no higher one is encoded. */ + /* */ + FT_CALLBACK_DEF( FT_ULong ) + code_to_next0( TT_CMapTable* cmap, + FT_ULong charCode ) + { + TT_CMap0* cmap0 = &cmap->c.cmap0; + + + while ( ++charCode <= 0xFF ) + if ( cmap0->glyphIdArray[charCode] ) + return ( charCode ); + return ( 0 ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ /* code_to_index2 */ /* */ /* <Description> */ @@ -536,6 +597,89 @@ /*************************************************************************/ /* */ /* <Function> */ + /* code_to_next2 */ + /* */ + /* <Description> */ + /* Find the next encoded character. Uses format 2. */ + /* */ + /* <Input> */ + /* charCode :: The wanted character code. */ + /* cmap2 :: A pointer to a cmap table in format 2. */ + /* */ + /* <Return> */ + /* Next encoded character. 0 if none exists. */ + /* */ + FT_CALLBACK_DEF( FT_ULong ) + code_to_next2( TT_CMapTable* cmap, + FT_ULong charCode ) + { + FT_UInt index1, offset; + FT_UInt char_lo; + FT_ULong char_hi; + TT_CMap2SubHeader* sh2; + TT_CMap2* cmap2; + + + cmap2 = &cmap->c.cmap2; + charCode++; + + /* + * This is relatively simplistic -- look for a subHeader containing + * glyphs and then walk to the first glyph in that subHeader. + */ + while ( charCode < 0x10000 ) + { + char_lo = (FT_UInt)( charCode & 0xFF ); + char_hi = charCode >> 8; + + if ( char_hi == 0 ) + { + /* an 8-bit character code -- we use the subHeader 0 in this case */ + /* to test whether the character code is in the charmap */ + index1 = cmap2->subHeaderKeys[char_lo]; + if ( index1 != 0 ) + { + charCode++; + continue; + } + } + else + { + /* a 16-bit character code */ + index1 = cmap2->subHeaderKeys[char_hi & 0xFF]; + if ( index1 == 0 ) + { + charCode = ( char_hi + 1 ) << 8; + continue; + } + } + + sh2 = cmap2->subHeaders + index1; + char_lo -= sh2->firstCode; + + if ( char_lo > (FT_UInt)sh2->entryCount ) + { + charCode = ( char_hi + 1 ) << 8; + continue; + } + + offset = sh2->idRangeOffset / 2 + char_lo; + if ( offset >= (FT_UInt)cmap2->numGlyphId || + cmap2->glyphIdArray[offset] == 0 ) + { + charCode++; + continue; + } + + return charCode; + } + return 0; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ /* code_to_index4 */ /* */ /* <Description> */ @@ -620,6 +764,73 @@ /*************************************************************************/ /* */ /* <Function> */ + /* code_to_next4 */ + /* */ + /* <Description> */ + /* Find the next encoded character. Uses format 4. */ + /* */ + /* <Input> */ + /* charCode :: The wanted character code. */ + /* cmap :: A pointer to a cmap table in format 4. */ + /* */ + /* <Return> */ + /* Next encoded character. 0 if none exists. */ + /* */ + FT_CALLBACK_DEF( FT_ULong ) + code_to_next4( TT_CMapTable* cmap, + FT_ULong charCode ) + { + FT_UInt index1, segCount; + TT_CMap4* cmap4; + TT_CMap4Segment *seg4, *limit; + + + cmap4 = &cmap->c.cmap4; + segCount = cmap4->segCountX2 / 2; + limit = cmap4->segments + segCount; + + charCode++; + + for ( seg4 = cmap4->segments; seg4 < limit; seg4++ ) + { + /* The ranges are sorted in increasing order. If we are out of */ + /* the range here, the char code isn't in the charmap, so exit. */ + + if ( charCode <= (FT_UInt)seg4->endCount ) + goto Found; + } + return 0; + + Found: + if ( charCode < seg4->startCount ) + charCode = seg4->startCount; + + /* if the idRangeOffset is 0, all chars in the map exist */ + + if ( seg4->idRangeOffset == 0 ) + return ( charCode ); + + while ( charCode <= (FT_UInt) seg4->endCount ) + { + /* otherwise, we must use the glyphIdArray to do it */ + index1 = (FT_UInt)( seg4->idRangeOffset / 2 + + ( charCode - seg4->startCount ) + + ( seg4 - cmap4->segments ) + - segCount ); + + if ( index1 < (FT_UInt)cmap4->numGlyphId && + cmap4->glyphIdArray[index1] != 0 ) + return ( charCode ); + charCode++; + } + + return 0; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ /* code_to_index6 */ /* */ /* <Description> */ @@ -653,6 +864,48 @@ /*************************************************************************/ /* */ /* <Function> */ + /* code_to_next6 */ + /* */ + /* <Description> */ + /* Find the next encoded character. Uses format 6. */ + /* */ + /* <Input> */ + /* charCode :: The wanted character code. */ + /* cmap :: A pointer to a cmap table in format 6. */ + /* */ + /* <Return> */ + /* Next encoded character. 0 if none exists. */ + /* */ + FT_CALLBACK_DEF( FT_ULong ) + code_to_next6( TT_CMapTable* cmap, + FT_ULong charCode ) + { + TT_CMap6* cmap6; + + + charCode++; + + cmap6 = &cmap->c.cmap6; + + if ( charCode < cmap6->firstCode ) + charCode = cmap6->firstCode; + + charCode -= cmap6->firstCode; + + while ( charCode < (FT_UInt)cmap6->entryCount ) + { + if ( cmap6->glyphIdArray[charCode] != 0 ) + return charCode + cmap6->firstCode; + charCode++; + } + + return 0; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ /* code_to_index8_12 */ /* */ /* <Description> */ @@ -718,6 +971,51 @@ /*************************************************************************/ /* */ /* <Function> */ + /* code_to_next8_12 */ + /* */ + /* <Description> */ + /* Find the next encoded character. Uses format 8 or 12. */ + /* */ + /* <Input> */ + /* charCode :: The wanted character code. */ + /* cmap :: A pointer to a cmap table in format 8 or 12. */ + /* */ + /* <Return> */ + /* Next encoded character. 0 if none exists. */ + /* */ + FT_CALLBACK_DEF( FT_ULong ) + code_to_next8_12( TT_CMapTable* cmap, + FT_ULong charCode ) + { + TT_CMap8_12* cmap8_12; + TT_CMapGroup *group, *limit; + + + charCode++; + cmap8_12 = &cmap->c.cmap8_12; + limit = cmap8_12->groups + cmap8_12->nGroups; + + for ( group = cmap8_12->groups; group < limit; group++ ) + { + /* the ranges are sorted in increasing order. If we are out of */ + /* the range here, the char code isn't in the charmap, so exit. */ + + if ( charCode <= group->endCharCode ) + goto Found; + } + return 0; + + Found: + if ( charCode < group->startCharCode ) + charCode = group->startCharCode; + + return charCode; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ /* code_to_index10 */ /* */ /* <Description> */ @@ -753,4 +1051,49 @@ } + /*************************************************************************/ + /* */ + /* <Function> */ + /* code_to_next10 */ + /* */ + /* <Description> */ + /* Find the next encoded character. Uses format 10. */ + /* */ + /* <Input> */ + /* charCode :: The wanted character code. */ + /* cmap :: A pointer to a cmap table in format 10. */ + /* */ + /* <Return> */ + /* Next encoded character. 0 if none exists. */ + /* */ + FT_CALLBACK_DEF( FT_ULong ) + code_to_next10( TT_CMapTable* cmap, + FT_ULong charCode ) + { + TT_CMap10* cmap10; + + + charCode++; + cmap10 = &cmap->c.cmap10; + + if ( charCode < cmap10->startCharCode ) + charCode = cmap10->startCharCode; + + charCode -= cmap10->startCharCode; + + /* the overflow trick for comparison works here also since the number */ + /* of glyphs (even if numChars is specified as ULong in the specs) in */ + /* an OpenType font is limited to 64k */ + + while ( charCode < cmap10->numChars ) + { + if ( cmap10->glyphs[charCode] ) + return ( charCode + cmap10->startCharCode ); + charCode++; + } + + return 0; + } + + /* END */ diff --git a/src/truetype/ttdriver.c b/src/truetype/ttdriver.c index 0b7d8f8d..5df3e318 100644 --- a/src/truetype/ttdriver.c +++ b/src/truetype/ttdriver.c @@ -394,6 +394,53 @@ /*************************************************************************/ + /* */ + /* <Function> */ + /* Get_Next_Char */ + /* */ + /* <Description> */ + /* Uses a charmap to return the next encoded char. */ + /* */ + /* <Input> */ + /* charmap :: A handle to the source charmap object. */ + /* charcode :: The character code. */ + /* */ + /* <Return> */ + /* Next char code. 0 means `no more encoded characters'. */ + /* */ + static FT_UInt + Get_Next_Char( TT_CharMap charmap, + FT_Long charcode ) + { + FT_Error error; + TT_Face face; + TT_CMapTable* cmap; + + + cmap = &charmap->cmap; + face = (TT_Face)charmap->root.face; + + /* Load table if needed */ + if ( !cmap->loaded ) + { + SFNT_Interface* sfnt = (SFNT_Interface*)face->sfnt; + + + error = sfnt->load_charmap( face, cmap, face->root.stream ); + if ( error ) + return 0; + + cmap->loaded = TRUE; + } + + if ( cmap->get_next_char ) + return cmap->get_next_char ( cmap, charcode ); + else + return 0; + } + + + /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /**** ****/ @@ -473,7 +520,9 @@ (FTDriver_getKerning) Get_Kerning, (FTDriver_attachFile) 0, - (FTDriver_getAdvances) 0 + (FTDriver_getAdvances) 0, + + (FTDriver_getNextChar) Get_Next_Char }; diff --git a/src/type1/t1driver.c b/src/type1/t1driver.c index 57e59f9a..b5bf444b 100644 --- a/src/type1/t1driver.c +++ b/src/type1/t1driver.c @@ -327,6 +327,100 @@ } + /*************************************************************************/ + /* */ + /* <Function> */ + /* Get_Next_Char */ + /* */ + /* <Description> */ + /* Uses a charmap to return the next encoded char. */ + /* */ + /* <Input> */ + /* charmap :: A handle to the source charmap object. */ + /* charcode :: The character code. */ + /* */ + /* <Return> */ + /* Next char code. 0 means `no more char codes'. */ + /* */ + static FT_Long + Get_Next_Char( FT_CharMap charmap, + FT_Long charcode ) + { + T1_Face face; + 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 */ + return psnames->next_unicode( &face->unicode_map, + (FT_ULong)charcode ); + + /*******************************************************************/ + /* */ + /* Custom Type 1 encoding */ + /* */ + case ft_encoding_adobe_custom: + { + T1_Encoding* encoding = &face->type1.encoding; + + + charcode++; + if ( charcode < encoding->code_first ) + charcode = encoding->code_first; + while ( charcode <= encoding->code_last ) + { + if ( encoding->char_index[charcode] ) + return charcode; + charcode++; + } + } + + /*******************************************************************/ + /* */ + /* Adobe Standard & Expert encoding support */ + /* */ + default: + while ( ++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 ) + continue; + + 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 ) + return charcode; + } + } + } + + return 0; + } + + FT_CALLBACK_TABLE_DEF const FT_Driver_Class t1_driver_class = { @@ -371,7 +465,9 @@ (FTDriver_getKerning) Get_Kerning, (FTDriver_attachFile) T1_Read_AFM, #endif - (FTDriver_getAdvances) 0 + (FTDriver_getAdvances) 0, + + (FTDriver_getNextChar) Get_Next_Char }; diff --git a/src/winfonts/winfnt.c b/src/winfonts/winfnt.c index 52976974..85297837 100644 --- a/src/winfonts/winfnt.c +++ b/src/winfonts/winfnt.c @@ -494,6 +494,27 @@ return result; } + static FT_Long + FNT_Get_Next_Char( FT_CharMap charmap, + FT_Long char_code ) + { + char_code++; + if ( charmap ) + { + FNT_Font* font = ((FNT_Face)charmap->face)->fonts; + FT_Long first = font->header.first_char; + + + if ( char_code < first ) + char_code = first; + if ( char_code <= font->header.last_char ) + return char_code; + } + else + return char_code; + return 0; + } + static FT_Error FNT_Load_Glyph( FT_GlyphSlot slot, @@ -622,7 +643,9 @@ (FTDriver_getKerning) 0, (FTDriver_attachFile) 0, - (FTDriver_getAdvances) 0 + (FTDriver_getAdvances) 0, + + (FTDriver_getNextChar) FNT_Get_Next_Char }; |