Export TT_New_GDEF_Table to create an empty GDEF table.
Fri Jan 10 18:56:36 2003 Owen Taylor <otaylor@redhat.com> * pango/opentype/ftxgdef.c: Export TT_New_GDEF_Table to create an empty GDEF table. * pango/opentype/pango-ot-info.c: If the font doesn't have a class definition table, synthesize one using the charmap and the unicode properties of characters in the charmap. (Needed to make things work with various old Arabic fonts, such as the KACST fonts)
This commit is contained in:
parent
db6bb4b034
commit
54e85cc0cf
|
@ -132,6 +132,37 @@
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
EXPORT_FUNC
|
||||||
|
FT_Error TT_New_GDEF_Table( FT_Face face,
|
||||||
|
TTO_GDEFHeader** retptr )
|
||||||
|
{
|
||||||
|
FT_Error error;
|
||||||
|
FT_Memory memory = face->memory;
|
||||||
|
|
||||||
|
TTO_GDEFHeader* gdef;
|
||||||
|
|
||||||
|
if ( !retptr )
|
||||||
|
return TT_Err_Invalid_Argument;
|
||||||
|
|
||||||
|
if ( ALLOC( gdef, sizeof( *gdef ) ) )
|
||||||
|
return error;
|
||||||
|
|
||||||
|
gdef->memory = face->memory;
|
||||||
|
|
||||||
|
gdef->GlyphClassDef.loaded = FALSE;
|
||||||
|
gdef->AttachList.loaded = FALSE;
|
||||||
|
gdef->LigCaretList.loaded = FALSE;
|
||||||
|
gdef->MarkAttachClassDef_offset = 0;
|
||||||
|
gdef->MarkAttachClassDef.loaded = FALSE;
|
||||||
|
|
||||||
|
gdef->LastGlyph = 0;
|
||||||
|
gdef->NewGlyphClasses = NULL;
|
||||||
|
|
||||||
|
*retptr = gdef;
|
||||||
|
|
||||||
|
return TT_Err_Ok;
|
||||||
|
}
|
||||||
|
|
||||||
EXPORT_FUNC
|
EXPORT_FUNC
|
||||||
FT_Error TT_Load_GDEF_Table( FT_Face face,
|
FT_Error TT_Load_GDEF_Table( FT_Face face,
|
||||||
TTO_GDEFHeader** retptr )
|
TTO_GDEFHeader** retptr )
|
||||||
|
@ -151,11 +182,9 @@
|
||||||
if (( error = tt_face->goto_table( tt_face, TTAG_GDEF, stream, 0 ) ))
|
if (( error = tt_face->goto_table( tt_face, TTAG_GDEF, stream, 0 ) ))
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
if ( ALLOC( gdef, sizeof( *gdef ) ) )
|
if (( error = TT_New_GDEF_Table ( face, &gdef ) ))
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
gdef->memory = face->memory;
|
|
||||||
|
|
||||||
base_offset = FILE_Pos();
|
base_offset = FILE_Pos();
|
||||||
|
|
||||||
/* skip version */
|
/* skip version */
|
||||||
|
@ -183,8 +212,6 @@
|
||||||
goto Fail0;
|
goto Fail0;
|
||||||
(void)FILE_Seek( cur_offset );
|
(void)FILE_Seek( cur_offset );
|
||||||
}
|
}
|
||||||
else
|
|
||||||
gdef->GlyphClassDef.loaded = FALSE;
|
|
||||||
|
|
||||||
if ( ACCESS_Frame( 2L ) )
|
if ( ACCESS_Frame( 2L ) )
|
||||||
goto Fail1;
|
goto Fail1;
|
||||||
|
@ -204,8 +231,6 @@
|
||||||
goto Fail1;
|
goto Fail1;
|
||||||
(void)FILE_Seek( cur_offset );
|
(void)FILE_Seek( cur_offset );
|
||||||
}
|
}
|
||||||
else
|
|
||||||
gdef->AttachList.loaded = FALSE;
|
|
||||||
|
|
||||||
if ( ACCESS_Frame( 2L ) )
|
if ( ACCESS_Frame( 2L ) )
|
||||||
goto Fail2;
|
goto Fail2;
|
||||||
|
@ -225,8 +250,6 @@
|
||||||
goto Fail2;
|
goto Fail2;
|
||||||
(void)FILE_Seek( cur_offset );
|
(void)FILE_Seek( cur_offset );
|
||||||
}
|
}
|
||||||
else
|
|
||||||
gdef->LigCaretList.loaded = FALSE;
|
|
||||||
|
|
||||||
/* OpenType 1.2 has introduced the `MarkAttachClassDef' field. We
|
/* OpenType 1.2 has introduced the `MarkAttachClassDef' field. We
|
||||||
first have to scan the LookupFlag values to find out whether we
|
first have to scan the LookupFlag values to find out whether we
|
||||||
|
@ -244,11 +267,6 @@
|
||||||
else
|
else
|
||||||
gdef->MarkAttachClassDef_offset = 0;
|
gdef->MarkAttachClassDef_offset = 0;
|
||||||
|
|
||||||
gdef->MarkAttachClassDef.loaded = FALSE;
|
|
||||||
|
|
||||||
gdef->LastGlyph = 0;
|
|
||||||
gdef->NewGlyphClasses = NULL;
|
|
||||||
|
|
||||||
*retptr = gdef;
|
*retptr = gdef;
|
||||||
|
|
||||||
return TT_Err_Ok;
|
return TT_Err_Ok;
|
||||||
|
|
|
@ -191,6 +191,10 @@ extern "C" {
|
||||||
/* EXPORT_DEF
|
/* EXPORT_DEF
|
||||||
FT_Error TT_Init_GDEF_Extension( TT_Engine engine ); */
|
FT_Error TT_Init_GDEF_Extension( TT_Engine engine ); */
|
||||||
|
|
||||||
|
EXPORT_FUNC
|
||||||
|
FT_Error TT_New_GDEF_Table( FT_Face face,
|
||||||
|
TTO_GDEFHeader** retptr );
|
||||||
|
|
||||||
EXPORT_DEF
|
EXPORT_DEF
|
||||||
FT_Error TT_Load_GDEF_Table( FT_Face face,
|
FT_Error TT_Load_GDEF_Table( FT_Face face,
|
||||||
TTO_GDEFHeader** gdef );
|
TTO_GDEFHeader** gdef );
|
||||||
|
|
|
@ -140,6 +140,108 @@ is_truetype (FT_Face face)
|
||||||
return strcmp (FT_MODULE_CLASS (face->driver)->module_name, "truetype") == 0;
|
return strcmp (FT_MODULE_CLASS (face->driver)->module_name, "truetype") == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct _GlyphInfo GlyphInfo;
|
||||||
|
|
||||||
|
struct _GlyphInfo {
|
||||||
|
FT_UShort glyph;
|
||||||
|
FT_UShort class;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
compare_glyph_info (gconstpointer a,
|
||||||
|
gconstpointer b)
|
||||||
|
{
|
||||||
|
const GlyphInfo *info_a = a;
|
||||||
|
const GlyphInfo *info_b = b;
|
||||||
|
|
||||||
|
return (info_a->glyph < info_b->glyph) ? -1 :
|
||||||
|
(info_a->glyph == info_b->glyph) ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make a guess at the appropriate class for a glyph given
|
||||||
|
* a character code that maps to the glyph
|
||||||
|
*/
|
||||||
|
static FT_UShort
|
||||||
|
get_glyph_class (gunichar charcode)
|
||||||
|
{
|
||||||
|
switch (g_unichar_type (charcode))
|
||||||
|
{
|
||||||
|
case G_UNICODE_COMBINING_MARK:
|
||||||
|
case G_UNICODE_ENCLOSING_MARK:
|
||||||
|
case G_UNICODE_NON_SPACING_MARK:
|
||||||
|
return 3; /* Mark glyph (non-spacing combining glyph) */
|
||||||
|
default:
|
||||||
|
return 1; /* Base glyph (single character, spacing glyph) */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Synthesize a GDEF table using the font's charmap and the
|
||||||
|
* unicode property database. We'll fill in class definitions
|
||||||
|
* for glyphs not in the charmap as we walk through the tables.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
synthesize_class_def (PangoOTInfo *info)
|
||||||
|
{
|
||||||
|
GArray *glyph_infos;
|
||||||
|
FT_UShort *glyph_indices;
|
||||||
|
FT_UShort *classes;
|
||||||
|
FT_ULong charcode;
|
||||||
|
FT_UInt glyph;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
if (info->face->charmap->encoding != ft_encoding_unicode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
glyph_infos = g_array_new (FALSE, FALSE, sizeof (GlyphInfo));
|
||||||
|
|
||||||
|
/* Collect all the glyphs in the charmap, and guess
|
||||||
|
* the appropriate classes for them
|
||||||
|
*/
|
||||||
|
charcode = FT_Get_First_Char (info->face, &glyph);
|
||||||
|
while (glyph != 0)
|
||||||
|
{
|
||||||
|
GlyphInfo glyph_info;
|
||||||
|
|
||||||
|
if (glyph > 65535)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
glyph_info.glyph = glyph;
|
||||||
|
glyph_info.class = get_glyph_class (charcode);
|
||||||
|
|
||||||
|
g_array_append_val (glyph_infos, glyph_info);
|
||||||
|
|
||||||
|
charcode = FT_Get_Next_Char (info->face, charcode, &glyph);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sort and remove duplicates
|
||||||
|
*/
|
||||||
|
g_array_sort (glyph_infos, compare_glyph_info);
|
||||||
|
|
||||||
|
glyph_indices = g_new (FT_UShort, glyph_infos->len);
|
||||||
|
classes = g_new (FT_UShort, glyph_infos->len);
|
||||||
|
|
||||||
|
for (i = 0, j = 0; i < glyph_infos->len; i++)
|
||||||
|
{
|
||||||
|
GlyphInfo *info = &g_array_index (glyph_infos, GlyphInfo, i);
|
||||||
|
|
||||||
|
if (j == 0 || info->glyph != glyph_indices[j - 1])
|
||||||
|
{
|
||||||
|
glyph_indices[j] = info->glyph;
|
||||||
|
classes[j] = info->class;
|
||||||
|
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_array_free (glyph_infos, TRUE);
|
||||||
|
|
||||||
|
TT_GDEF_Build_ClassDefinition (info->gdef, info->face->num_glyphs, j,
|
||||||
|
glyph_indices, classes);
|
||||||
|
|
||||||
|
g_free (glyph_indices);
|
||||||
|
g_free (classes);
|
||||||
|
}
|
||||||
|
|
||||||
TTO_GDEF
|
TTO_GDEF
|
||||||
pango_ot_info_get_gdef (PangoOTInfo *info)
|
pango_ot_info_get_gdef (PangoOTInfo *info)
|
||||||
{
|
{
|
||||||
|
@ -157,6 +259,12 @@ pango_ot_info_get_gdef (PangoOTInfo *info)
|
||||||
|
|
||||||
if (error && error != TT_Err_Table_Missing)
|
if (error && error != TT_Err_Table_Missing)
|
||||||
g_warning ("Error loading GDEF table %d", error);
|
g_warning ("Error loading GDEF table %d", error);
|
||||||
|
|
||||||
|
if (!info->gdef)
|
||||||
|
error = TT_New_GDEF_Table (info->face, &info->gdef);
|
||||||
|
|
||||||
|
if (info->gdef && !info->gdef->GlyphClassDef.loaded)
|
||||||
|
synthesize_class_def (info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue