[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 6f87ee0e3a0: Enumerate default UVS glyphs
From: |
Po Lu |
Subject: |
master 6f87ee0e3a0: Enumerate default UVS glyphs |
Date: |
Sat, 21 Oct 2023 21:06:46 -0400 (EDT) |
branch: master
commit 6f87ee0e3a0727e16079778a4264e6e35cd7f3a8
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>
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.
---
src/sfnt.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++-
src/sfnt.h | 6 ++++++
src/sfntfont.c | 68 ++++++++++++++++++++++++++++++++++++++++++++--------------
3 files changed, 116 insertions(+), 17 deletions(-)
diff --git a/src/sfnt.c b/src/sfnt.c
index 348cff604af..01d061be79c 100644
--- a/src/sfnt.c
+++ b/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;
diff --git a/src/sfnt.h b/src/sfnt.h
index 6602d240051..41c1f6f74e8 100644
--- a/src/sfnt.h
+++ b/src/sfnt.h
@@ -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
diff --git a/src/sfntfont.c b/src/sfntfont.c
index 2c58de31a16..35b37396ccd 100644
--- a/src/sfntfont.c
+++ b/src/sfntfont.c
@@ -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 */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master 6f87ee0e3a0: Enumerate default UVS glyphs,
Po Lu <=