ref: 0f7c2f1aa58c2251d6c1a3f388a50bfa97cb097f
parent: 3604d5f5581bdf39d990dcc9b0e21a828dd0f24a
author: Werner Lemberg <[email protected]>
date: Mon Feb 4 15:55:58 EST 2002
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.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,43 @@
+2002-02-04 Keith Packard <[email protected]>
+
+ 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.
+
2002-02-02 Keith Packard <[email protected]>
* builds/unix/freetype-config.in: Add missing `fi'.
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -122,6 +122,7 @@
/* FT_Set_Transform */
/* FT_Load_Glyph */
/* FT_Get_Char_Index */
+ /* FT_Get_Next_Char */
/* FT_Get_Name_Index */
/* FT_Load_Char */
/* */
@@ -2389,6 +2390,27 @@
FT_EXPORT( FT_UInt )
FT_Get_Char_Index( FT_Face face,
FT_ULong charcode );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Get_Next_Char */
+ /* */
+ /* <Description> */
+ /* Returns the next charcode that is defined in the charmap. */
+ /* */
+ /* <Input> */
+ /* face :: A handle to the source face object. */
+ /* */
+ /* charcode :: The character code. */
+ /* */
+ /* <Return> */
+ /* The charcode. 0 means `no encoded values above charcode'. */
+ /* */
+ FT_EXPORT( FT_ULong )
+ FT_Get_Next_Char( FT_Face face,
+ FT_ULong charcode );
/*************************************************************************/
--- a/include/freetype/internal/ftdriver.h
+++ b/include/freetype/internal/ftdriver.h
@@ -75,6 +75,10 @@
(*FTDriver_getCharIndex)( FT_CharMap charmap,
FT_Long charcode );
+ typedef FT_Long
+ (*FTDriver_getNextChar)( FT_CharMap charmap,
+ FT_Long charcode );
+
typedef FT_Error
(*FTDriver_getKerning)( FT_Face face,
FT_UInt left_glyph,
@@ -189,6 +193,7 @@
FTDriver_getAdvances get_advances;
+ FTDriver_getNextChar get_next_char;
} FT_Driver_Class;
--- a/include/freetype/internal/psnames.h
+++ b/include/freetype/internal/psnames.h
@@ -166,7 +166,11 @@
(*PS_Lookup_Unicode_Func)( PS_Unicodes* unicodes,
FT_UInt unicode );
+ typedef FT_ULong
+ (*PS_Next_Unicode_Func)( PS_Unicodes* unicodes,
+ FT_ULong unicode );
+
/*************************************************************************/
/* */
/* <Struct> */
@@ -221,6 +225,7 @@
const unsigned short* adobe_std_encoding;
const unsigned short* adobe_expert_encoding;
+ PS_Next_Unicode_Func next_unicode;
} PSNames_Interface;
--- a/include/freetype/internal/tttypes.h
+++ b/include/freetype/internal/tttypes.h
@@ -1049,7 +1049,11 @@
(*TT_CharMap_Func)( TT_CMapTable* charmap,
FT_ULong char_code );
+ typedef FT_ULong
+ (*TT_CharNext_Func)( TT_CMapTable* charmap,
+ FT_ULong char_code );
+
/* charmap table */
struct TT_CMapTable_
{
@@ -1072,6 +1076,7 @@
} c;
TT_CharMap_Func get_index;
+ TT_CharNext_Func get_next_char;
};
--- 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 */
--- 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
};
--- 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
};
--- a/src/pcf/pcfdriver.c
+++ b/src/pcf/pcfdriver.c
@@ -276,6 +276,46 @@
}
+ 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 @@
(FTDriver_getKerning) 0,
(FTDriver_attachFile) 0,
- (FTDriver_getAdvances) 0
+ (FTDriver_getAdvances) 0,
+
+ (FTDriver_getNextChar) PCF_Get_Next_Char
};
--- a/src/pcf/pcfread.c
+++ b/src/pcf/pcfread.c
@@ -1021,10 +1021,14 @@
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 @@
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;
--- 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 */
+
};
--- a/src/sfnt/ttcmap.c
+++ b/src/sfnt/ttcmap.c
@@ -38,27 +38,51 @@
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 );
+
/*************************************************************************/
/* */
/* <Function> */
@@ -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> */
@@ -750,6 +1048,51 @@
result = cmap10->glyphs[charCode];
return result;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* <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;
}
--- a/src/truetype/ttdriver.c
+++ b/src/truetype/ttdriver.c
@@ -394,8 +394,55 @@
/*************************************************************************/
+ /* */
+ /* <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;
+ }
+
+
/*************************************************************************/
/*************************************************************************/
+ /*************************************************************************/
/**** ****/
/**** ****/
/**** D R I V E R I N T E R F A C E ****/
@@ -473,7 +520,9 @@
(FTDriver_getKerning) Get_Kerning,
(FTDriver_attachFile) 0,
- (FTDriver_getAdvances) 0
+ (FTDriver_getAdvances) 0,
+
+ (FTDriver_getNextChar) Get_Next_Char
};
--- 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
};
--- a/src/winfonts/winfnt.c
+++ b/src/winfonts/winfnt.c
@@ -494,7 +494,28 @@
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,
FNT_Size size,
@@ -622,7 +643,9 @@
(FTDriver_getKerning) 0,
(FTDriver_attachFile) 0,
- (FTDriver_getAdvances) 0
+ (FTDriver_getAdvances) 0,
+
+ (FTDriver_getNextChar) FNT_Get_Next_Char
};