Enumerate default UVS glyphs
* src/sfnt.c (sfnt_compare_unicode_value_range) (sfnt_is_character_default): New functions. (sfnt_test_uvs): Print and verify the default UVS table. * src/sfnt.h: Update prototypes. * src/sfntfont.c (sfntfont_get_variation_glyphs): Index the cmap with the default glyph, and insert it within VARIATIONS if character is present within a selector record's default UVS table.
This commit is contained in:
parent
8c15515b62
commit
6f87ee0e3a
3 changed files with 116 additions and 17 deletions
59
src/sfnt.c
59
src/sfnt.c
|
@ -12717,6 +12717,26 @@ sfnt_compare_uvs_mapping (const void *k, const void *v)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* Compare *(sfnt_char *) K to the Unicode value range V. */
|
||||
|
||||
static int
|
||||
sfnt_compare_unicode_value_range (const void *k, const void *v)
|
||||
{
|
||||
const sfnt_char *key;
|
||||
const struct sfnt_unicode_value_range *value;
|
||||
|
||||
key = k;
|
||||
value = v;
|
||||
|
||||
if (*key < value->start_unicode_value)
|
||||
return -1;
|
||||
else if ((*key - value->start_unicode_value
|
||||
<= value->additional_count))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Return the ID of a variation glyph for the character C in the
|
||||
nondefault UVS mapping table UVS.
|
||||
|
||||
|
@ -12736,6 +12756,21 @@ sfnt_variation_glyph_for_char (struct sfnt_nondefault_uvs_table *uvs,
|
|||
return mapping ? mapping->base_character_value : 0;
|
||||
}
|
||||
|
||||
/* Return whether the character C is present in the default UVS
|
||||
mapping table UVS. */
|
||||
|
||||
TEST_STATIC bool
|
||||
sfnt_is_character_default (struct sfnt_default_uvs_table *uvs,
|
||||
sfnt_char c)
|
||||
{
|
||||
/* UVS->ranges comprises ranges of characters sorted in increasing
|
||||
order; these ranges cannot overlap. */
|
||||
|
||||
return (bsearch (&c, uvs->ranges, uvs->num_unicode_value_ranges,
|
||||
sizeof *uvs->ranges,
|
||||
sfnt_compare_unicode_value_range) != NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if defined HAVE_MMAP && !defined TEST
|
||||
|
@ -19191,10 +19226,11 @@ static void
|
|||
sfnt_test_uvs (int fd, struct sfnt_cmap_format_14 *format14)
|
||||
{
|
||||
struct sfnt_uvs_context *context;
|
||||
size_t i, j;
|
||||
size_t i, j, k;
|
||||
sfnt_glyph glyph;
|
||||
sfnt_char c;
|
||||
struct sfnt_nondefault_uvs_table *uvs;
|
||||
struct sfnt_default_uvs_table *default_uvs;
|
||||
|
||||
context = sfnt_create_uvs_context (format14, fd);
|
||||
|
||||
|
@ -19209,6 +19245,27 @@ sfnt_test_uvs (int fd, struct sfnt_cmap_format_14 *format14)
|
|||
|
||||
for (i = 0; i < context->num_records; ++i)
|
||||
{
|
||||
if (context->records[i].default_uvs)
|
||||
{
|
||||
default_uvs = context->records[i].default_uvs;
|
||||
|
||||
for (j = 0; j < default_uvs->num_unicode_value_ranges; ++j)
|
||||
{
|
||||
fprintf (stderr, " Default UVS: %u, %u\n",
|
||||
default_uvs->ranges[j].start_unicode_value,
|
||||
default_uvs->ranges[j].additional_count);
|
||||
|
||||
c = default_uvs->ranges[j].start_unicode_value;
|
||||
k = 0;
|
||||
|
||||
for (; k <= default_uvs->ranges[j].additional_count; ++k)
|
||||
{
|
||||
if (!sfnt_is_character_default (default_uvs, c + k))
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!context->records[i].nondefault_uvs)
|
||||
continue;
|
||||
|
||||
|
|
|
@ -1526,6 +1526,12 @@ extern sfnt_glyph sfnt_variation_glyph_for_char (PROTOTYPE);
|
|||
|
||||
#undef PROTOTYPE
|
||||
|
||||
#define PROTOTYPE struct sfnt_default_uvs_table *, sfnt_char
|
||||
|
||||
extern bool sfnt_is_character_default (PROTOTYPE);
|
||||
|
||||
#undef PROTOTYPE
|
||||
|
||||
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
|
|
|
@ -3720,9 +3720,10 @@ sfntfont_get_variation_glyphs (struct font *font, int c,
|
|||
unsigned variations[256])
|
||||
{
|
||||
struct sfnt_font_info *info;
|
||||
size_t i;
|
||||
size_t i, index;
|
||||
int n;
|
||||
struct sfnt_mapped_variation_selector_record *record;
|
||||
sfnt_glyph default_glyph;
|
||||
|
||||
info = (struct sfnt_font_info *) font;
|
||||
n = 0;
|
||||
|
@ -3743,12 +3744,37 @@ sfntfont_get_variation_glyphs (struct font *font, int c,
|
|||
&& info->uvs->records[i].selector < 0xfe00)
|
||||
++i;
|
||||
|
||||
/* Get the glyph represented by C, used when C is present within a
|
||||
default value table. */
|
||||
|
||||
default_glyph = sfntfont_lookup_glyph (info, c);
|
||||
|
||||
/* Fill in selectors 0 to 15. */
|
||||
|
||||
while (i < info->uvs->num_records
|
||||
&& info->uvs->records[i].selector <= 0xfe0f)
|
||||
{
|
||||
record = &info->uvs->records[i];
|
||||
index = info->uvs->records[i].selector - 0xfe00 + 16;
|
||||
|
||||
/* Handle invalid unsorted tables. */
|
||||
|
||||
if (record->selector < 0xfe00)
|
||||
return 0;
|
||||
|
||||
/* If there are default mappings in this record, ascertain if
|
||||
this glyph matches one of them. */
|
||||
|
||||
if (record->default_uvs
|
||||
&& sfnt_is_character_default (record->default_uvs, c))
|
||||
{
|
||||
variations[index] = default_glyph;
|
||||
|
||||
if (default_glyph)
|
||||
++n;
|
||||
|
||||
goto next_selector;
|
||||
}
|
||||
|
||||
/* If record has no non-default mappings, continue on to the
|
||||
next selector. */
|
||||
|
@ -3756,18 +3782,13 @@ sfntfont_get_variation_glyphs (struct font *font, int c,
|
|||
if (!record->nondefault_uvs)
|
||||
goto next_selector;
|
||||
|
||||
/* Handle invalid unsorted tables. */
|
||||
|
||||
if (record->selector < 0xfe00)
|
||||
return 0;
|
||||
|
||||
/* Find the glyph ID associated with C and put it in
|
||||
VARIATIONS. */
|
||||
|
||||
variations[info->uvs->records[i].selector - 0xfe00]
|
||||
variations[index]
|
||||
= sfnt_variation_glyph_for_char (record->nondefault_uvs, c);
|
||||
|
||||
if (variations[info->uvs->records[i].selector - 0xfe00])
|
||||
if (variations[index])
|
||||
++n;
|
||||
|
||||
next_selector:
|
||||
|
@ -3787,6 +3808,26 @@ sfntfont_get_variation_glyphs (struct font *font, int c,
|
|||
&& info->uvs->records[i].selector <= 0xe01ef)
|
||||
{
|
||||
record = &info->uvs->records[i];
|
||||
index = info->uvs->records[i].selector - 0xe0100 + 16;
|
||||
|
||||
/* Handle invalid unsorted tables. */
|
||||
|
||||
if (record->selector < 0xe0100)
|
||||
return 0;
|
||||
|
||||
/* If there are default mappings in this record, ascertain if
|
||||
this glyph matches one of them. */
|
||||
|
||||
if (record->default_uvs
|
||||
&& sfnt_is_character_default (record->default_uvs, c))
|
||||
{
|
||||
variations[index] = default_glyph;
|
||||
|
||||
if (default_glyph)
|
||||
++n;
|
||||
|
||||
goto next_selector_1;
|
||||
}
|
||||
|
||||
/* If record has no non-default mappings, continue on to the
|
||||
next selector. */
|
||||
|
@ -3794,18 +3835,13 @@ sfntfont_get_variation_glyphs (struct font *font, int c,
|
|||
if (!record->nondefault_uvs)
|
||||
goto next_selector_1;
|
||||
|
||||
/* Handle invalid unsorted tables. */
|
||||
|
||||
if (record->selector < 0xe0100)
|
||||
return 0;
|
||||
|
||||
/* Find the glyph ID associated with C and put it in
|
||||
VARIATIONS. */
|
||||
|
||||
variations[info->uvs->records[i].selector - 0xe0100 + 16]
|
||||
variations[index]
|
||||
= sfnt_variation_glyph_for_char (record->nondefault_uvs, c);
|
||||
|
||||
if (variations[info->uvs->records[i].selector - 0xe0100 + 16])
|
||||
if (variations[index])
|
||||
++n;
|
||||
|
||||
next_selector_1:
|
||||
|
@ -3841,7 +3877,7 @@ sfntfont_detect_sigbus (void *addr)
|
|||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* HAVE_MMAP */
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue