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.
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);
+}
+
\f
#if defined HAVE_MMAP && !defined TEST
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);
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;
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;
&& 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. */
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:
&& 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. */
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:
return false;
}
-#endif
+#endif /* HAVE_MMAP */
\f