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.
This commit is contained in:
Werner Lemberg 2002-02-04 20:55:58 +00:00
parent 5b4691278c
commit 08270698e7
15 changed files with 863 additions and 21 deletions

View File

@ -1,3 +1,43 @@
2002-02-04 Keith Packard <keithp@keithp.com>
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 <keithp@keithp.com>
* builds/unix/freetype-config.in: Add missing `fi'.

View File

@ -122,6 +122,7 @@ FT_BEGIN_HEADER
/* FT_Set_Transform */
/* FT_Load_Glyph */
/* FT_Get_Char_Index */
/* FT_Get_Next_Char */
/* FT_Get_Name_Index */
/* FT_Load_Char */
/* */
@ -2391,6 +2392,27 @@ FT_BEGIN_HEADER
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 );
/*************************************************************************/
/* */
/* <Function> */

View File

@ -75,6 +75,10 @@ FT_BEGIN_HEADER
(*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 @@ FT_BEGIN_HEADER
FTDriver_getAdvances get_advances;
FTDriver_getNextChar get_next_char;
} FT_Driver_Class;

View File

@ -166,6 +166,10 @@ FT_BEGIN_HEADER
(*PS_Lookup_Unicode_Func)( PS_Unicodes* unicodes,
FT_UInt unicode );
typedef FT_ULong
(*PS_Next_Unicode_Func)( PS_Unicodes* unicodes,
FT_ULong unicode );
/*************************************************************************/
/* */
@ -221,6 +225,7 @@ FT_BEGIN_HEADER
const unsigned short* adobe_std_encoding;
const unsigned short* adobe_expert_encoding;
PS_Next_Unicode_Func next_unicode;
} PSNames_Interface;

View File

@ -1049,6 +1049,10 @@ FT_BEGIN_HEADER
(*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 @@ FT_BEGIN_HEADER
} c;
TT_CharMap_Func get_index;
TT_CharNext_Func get_next_char;
};

View File

@ -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 */

View File

@ -317,6 +317,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> */
@ -454,7 +498,9 @@
(FTDriver_getKerning) Get_Kerning,
(FTDriver_attachFile) 0,
(FTDriver_getAdvances) 0
(FTDriver_getAdvances) 0,
(FTDriver_getNextChar) cff_get_next_char
};

View File

@ -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
};

View File

@ -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
};

View File

@ -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;

View File

@ -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 */
};

View File

@ -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 */
@ -468,6 +498,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> */
@ -533,6 +594,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> */
@ -617,6 +761,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> */
@ -650,6 +861,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> */
@ -715,6 +968,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> */
@ -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 */

View File

@ -393,6 +393,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
};

View File

@ -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
};

View File

@ -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
};