[sfnt] Synthesize a Unicode charmap if one is missing.

* src/sfnt/ttcmap.h (tt_cmap_unicode_class_rec): Declare it.
* src/sfnt/ttcmap.c (tt_get_glyph_name, tt_cmap_unicode_init,
tt_cmap_unicode_done, tt_cmap_unicode_char_index,
tt_cmap_unicode_char_next, tt_cmap_unicode_class_rec): Implement
synthetic Unicode charmap class.
(tt_get_cmap_info): Make sure the callback is available.

* src/sfnt/sfobjs.c (sfnt_load_face)
[FT_CONFIG_OPTION_POSTSCRIPT_NAMES]: If Unicode charmap is missing,
synthesize one.

* include/freetype/config/ftoption.h: Document it.
* devel/ftoption.h: Ditto.
This commit is contained in:
Alexei Podtelezhnikov 2017-06-21 22:52:37 -04:00
parent 390048fa46
commit 75cb071b3f
6 changed files with 163 additions and 6 deletions

View File

@ -1,3 +1,21 @@
2017-06-21 Alexei Podtelezhnikov <apodtele@gmail.com>
[sfnt] Synthesize a Unicode charmap if one is missing.
* src/sfnt/ttcmap.h (tt_cmap_unicode_class_rec): Declare it.
* src/sfnt/ttcmap.c (tt_get_glyph_name, tt_cmap_unicode_init,
tt_cmap_unicode_done, tt_cmap_unicode_char_index,
tt_cmap_unicode_char_next, tt_cmap_unicode_class_rec): Implement
synthetic Unicode charmap class.
(tt_get_cmap_info): Make sure the callback is available.
* src/sfnt/sfobjs.c (sfnt_load_face)
[FT_CONFIG_OPTION_POSTSCRIPT_NAMES]: If Unicode charmap is missing,
synthesize one.
* include/freetype/config/ftoption.h: Document it.
* devel/ftoption.h: Ditto.
2017-06-20 Tony Theodore <tonyt@logyst.com>
Fix pkg-config in freetype-config for cross-compiling (#51274).

View File

@ -327,7 +327,7 @@ FT_BEGIN_HEADER
/* */
/* - The TrueType driver will provide its own set of glyph names, */
/* if you build it to support postscript names in the TrueType */
/* `post' table. */
/* `post' table, but will not synthesize a missing Unicode charmap. */
/* */
/* - The Type 1 driver will not be able to synthesize a Unicode */
/* charmap out of the glyphs found in the fonts. */

View File

@ -327,7 +327,7 @@ FT_BEGIN_HEADER
/* */
/* - The TrueType driver will provide its own set of glyph names, */
/* if you build it to support postscript names in the TrueType */
/* `post' table. */
/* `post' table, but will not synthesize a missing Unicode charmap. */
/* */
/* - The Type 1 driver will not be able to synthesize a Unicode */
/* charmap out of the glyphs found in the fonts. */

View File

@ -1464,7 +1464,8 @@
/* Polish the charmaps. */
/* */
/* Try to set the charmap encoding according to the platform & */
/* encoding ID of each charmap. */
/* encoding ID of each charmap. Emulate Unicode charmap if one */
/* is missing. */
/* */
tt_face_build_cmaps( face ); /* ignore errors */
@ -1472,7 +1473,10 @@
/* set the encoding fields */
{
FT_Int m;
FT_Int m;
#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
FT_Bool has_unicode = FALSE;
#endif
for ( m = 0; m < root->num_charmaps; m++ )
@ -1482,6 +1486,33 @@
charmap->encoding = sfnt_find_encoding( charmap->platform_id,
charmap->encoding_id );
#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
if ( charmap->encoding == FT_ENCODING_UNICODE )
has_unicode = TRUE;
}
/* synthesize Unicode charmap if one is missing */
if ( !has_unicode )
{
FT_CharMapRec cmaprec;
cmaprec.face = root;
cmaprec.platform_id = TT_PLATFORM_MICROSOFT;
cmaprec.encoding_id = TT_MS_ID_UNICODE_CS;
cmaprec.encoding = FT_ENCODING_UNICODE;
error = FT_CMap_New( (FT_CMap_Class)&tt_cmap_unicode_class_rec,
NULL, &cmaprec, NULL );
if ( error &&
FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) )
FT_TRACE2(( "sfnt_load_face: failed to emulate Unicode\n" ));
#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
}
}

View File

@ -3622,6 +3622,110 @@
#endif /* TT_CONFIG_CMAP_FORMAT_14 */
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** SYNTHETIC UNICODE *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/* This charmap is generated using postscript glyph names. */
#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
FT_CALLBACK_DEF( const char * )
tt_get_glyph_name( TT_Face face,
FT_UInt idx )
{
FT_String* PSname;
tt_face_get_ps_name( face, idx, &PSname );
return PSname;
}
FT_CALLBACK_DEF( FT_Error )
tt_cmap_unicode_init( PS_Unicodes unicodes,
FT_Pointer pointer )
{
TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes );
FT_Memory memory = FT_FACE_MEMORY( face );
FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames;
FT_UNUSED( pointer );
return psnames->unicodes_init( memory,
unicodes,
face->root.num_glyphs,
(PS_GetGlyphNameFunc)&tt_get_glyph_name,
(PS_FreeGlyphNameFunc)NULL,
(FT_Pointer)face );
}
FT_CALLBACK_DEF( void )
tt_cmap_unicode_done( PS_Unicodes unicodes )
{
FT_Face face = FT_CMAP_FACE( unicodes );
FT_Memory memory = FT_FACE_MEMORY( face );
FT_FREE( unicodes->maps );
unicodes->num_maps = 0;
}
FT_CALLBACK_DEF( FT_UInt )
tt_cmap_unicode_char_index( PS_Unicodes unicodes,
FT_UInt32 char_code )
{
TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes );
FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames;
return psnames->unicodes_char_index( unicodes, char_code );
}
FT_CALLBACK_DEF( FT_UInt32 )
tt_cmap_unicode_char_next( PS_Unicodes unicodes,
FT_UInt32 *pchar_code )
{
TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes );
FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames;
return psnames->unicodes_char_next( unicodes, pchar_code );
}
FT_DEFINE_TT_CMAP(
tt_cmap_unicode_class_rec,
sizeof ( PS_UnicodesRec ),
(FT_CMap_InitFunc) tt_cmap_unicode_init, /* init */
(FT_CMap_DoneFunc) tt_cmap_unicode_done, /* done */
(FT_CMap_CharIndexFunc)tt_cmap_unicode_char_index, /* char_index */
(FT_CMap_CharNextFunc) tt_cmap_unicode_char_next, /* char_next */
(FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */
(FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */
(FT_CMap_VariantListFunc) NULL, /* variant_list */
(FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */
(FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */
-1,
(TT_CMap_ValidateFunc)NULL, /* validate */
(TT_CMap_Info_GetFunc)NULL /* get_cmap_info */
)
#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
#ifndef FT_CONFIG_OPTION_PIC
static const TT_CMap_Class tt_cmap_classes[] =
@ -3801,8 +3905,10 @@
FT_CMap cmap = (FT_CMap)charmap;
TT_CMap_Class clazz = (TT_CMap_Class)cmap->clazz;
return clazz->get_cmap_info( charmap, cmap_info );
if ( clazz->get_cmap_info )
return clazz->get_cmap_info( charmap, cmap_info );
else
return FT_THROW( Invalid_CharMap_Format );
}

View File

@ -141,6 +141,8 @@ FT_BEGIN_HEADER
#define TT_VALID_GLYPH_COUNT( x ) TT_VALIDATOR( x )->num_glyphs
FT_CALLBACK_TABLE const TT_CMap_ClassRec tt_cmap_unicode_class_rec;
FT_LOCAL( FT_Error )
tt_face_build_cmaps( TT_Face face );