diff options
| author | Po Lu | 2023-10-22 09:06:28 +0800 |
|---|---|---|
| committer | Po Lu | 2023-10-22 09:06:28 +0800 |
| commit | 6f87ee0e3a0727e16079778a4264e6e35cd7f3a8 (patch) | |
| tree | af64e5249371cb4c7e44b13e426c177181cadc60 /src | |
| parent | 8c15515b62cacae06dd3ced6492142ce185e5adb (diff) | |
| download | emacs-6f87ee0e3a0727e16079778a4264e6e35cd7f3a8.tar.gz emacs-6f87ee0e3a0727e16079778a4264e6e35cd7f3a8.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/sfnt.c | 59 | ||||
| -rw-r--r-- | src/sfnt.h | 6 | ||||
| -rw-r--r-- | 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) | |||
| 12717 | return 1; | 12717 | return 1; |
| 12718 | } | 12718 | } |
| 12719 | 12719 | ||
| 12720 | /* Compare *(sfnt_char *) K to the Unicode value range V. */ | ||
| 12721 | |||
| 12722 | static int | ||
| 12723 | sfnt_compare_unicode_value_range (const void *k, const void *v) | ||
| 12724 | { | ||
| 12725 | const sfnt_char *key; | ||
| 12726 | const struct sfnt_unicode_value_range *value; | ||
| 12727 | |||
| 12728 | key = k; | ||
| 12729 | value = v; | ||
| 12730 | |||
| 12731 | if (*key < value->start_unicode_value) | ||
| 12732 | return -1; | ||
| 12733 | else if ((*key - value->start_unicode_value | ||
| 12734 | <= value->additional_count)) | ||
| 12735 | return 0; | ||
| 12736 | |||
| 12737 | return 1; | ||
| 12738 | } | ||
| 12739 | |||
| 12720 | /* Return the ID of a variation glyph for the character C in the | 12740 | /* Return the ID of a variation glyph for the character C in the |
| 12721 | nondefault UVS mapping table UVS. | 12741 | nondefault UVS mapping table UVS. |
| 12722 | 12742 | ||
| @@ -12736,6 +12756,21 @@ sfnt_variation_glyph_for_char (struct sfnt_nondefault_uvs_table *uvs, | |||
| 12736 | return mapping ? mapping->base_character_value : 0; | 12756 | return mapping ? mapping->base_character_value : 0; |
| 12737 | } | 12757 | } |
| 12738 | 12758 | ||
| 12759 | /* Return whether the character C is present in the default UVS | ||
| 12760 | mapping table UVS. */ | ||
| 12761 | |||
| 12762 | TEST_STATIC bool | ||
| 12763 | sfnt_is_character_default (struct sfnt_default_uvs_table *uvs, | ||
| 12764 | sfnt_char c) | ||
| 12765 | { | ||
| 12766 | /* UVS->ranges comprises ranges of characters sorted in increasing | ||
| 12767 | order; these ranges cannot overlap. */ | ||
| 12768 | |||
| 12769 | return (bsearch (&c, uvs->ranges, uvs->num_unicode_value_ranges, | ||
| 12770 | sizeof *uvs->ranges, | ||
| 12771 | sfnt_compare_unicode_value_range) != NULL); | ||
| 12772 | } | ||
| 12773 | |||
| 12739 | 12774 | ||
| 12740 | 12775 | ||
| 12741 | #if defined HAVE_MMAP && !defined TEST | 12776 | #if defined HAVE_MMAP && !defined TEST |
| @@ -19191,10 +19226,11 @@ static void | |||
| 19191 | sfnt_test_uvs (int fd, struct sfnt_cmap_format_14 *format14) | 19226 | sfnt_test_uvs (int fd, struct sfnt_cmap_format_14 *format14) |
| 19192 | { | 19227 | { |
| 19193 | struct sfnt_uvs_context *context; | 19228 | struct sfnt_uvs_context *context; |
| 19194 | size_t i, j; | 19229 | size_t i, j, k; |
| 19195 | sfnt_glyph glyph; | 19230 | sfnt_glyph glyph; |
| 19196 | sfnt_char c; | 19231 | sfnt_char c; |
| 19197 | struct sfnt_nondefault_uvs_table *uvs; | 19232 | struct sfnt_nondefault_uvs_table *uvs; |
| 19233 | struct sfnt_default_uvs_table *default_uvs; | ||
| 19198 | 19234 | ||
| 19199 | context = sfnt_create_uvs_context (format14, fd); | 19235 | context = sfnt_create_uvs_context (format14, fd); |
| 19200 | 19236 | ||
| @@ -19209,6 +19245,27 @@ sfnt_test_uvs (int fd, struct sfnt_cmap_format_14 *format14) | |||
| 19209 | 19245 | ||
| 19210 | for (i = 0; i < context->num_records; ++i) | 19246 | for (i = 0; i < context->num_records; ++i) |
| 19211 | { | 19247 | { |
| 19248 | if (context->records[i].default_uvs) | ||
| 19249 | { | ||
| 19250 | default_uvs = context->records[i].default_uvs; | ||
| 19251 | |||
| 19252 | for (j = 0; j < default_uvs->num_unicode_value_ranges; ++j) | ||
| 19253 | { | ||
| 19254 | fprintf (stderr, " Default UVS: %u, %u\n", | ||
| 19255 | default_uvs->ranges[j].start_unicode_value, | ||
| 19256 | default_uvs->ranges[j].additional_count); | ||
| 19257 | |||
| 19258 | c = default_uvs->ranges[j].start_unicode_value; | ||
| 19259 | k = 0; | ||
| 19260 | |||
| 19261 | for (; k <= default_uvs->ranges[j].additional_count; ++k) | ||
| 19262 | { | ||
| 19263 | if (!sfnt_is_character_default (default_uvs, c + k)) | ||
| 19264 | abort (); | ||
| 19265 | } | ||
| 19266 | } | ||
| 19267 | } | ||
| 19268 | |||
| 19212 | if (!context->records[i].nondefault_uvs) | 19269 | if (!context->records[i].nondefault_uvs) |
| 19213 | continue; | 19270 | continue; |
| 19214 | 19271 | ||
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); | |||
| 1526 | 1526 | ||
| 1527 | #undef PROTOTYPE | 1527 | #undef PROTOTYPE |
| 1528 | 1528 | ||
| 1529 | #define PROTOTYPE struct sfnt_default_uvs_table *, sfnt_char | ||
| 1530 | |||
| 1531 | extern bool sfnt_is_character_default (PROTOTYPE); | ||
| 1532 | |||
| 1533 | #undef PROTOTYPE | ||
| 1534 | |||
| 1529 | 1535 | ||
| 1530 | 1536 | ||
| 1531 | #ifdef HAVE_MMAP | 1537 | #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, | |||
| 3720 | unsigned variations[256]) | 3720 | unsigned variations[256]) |
| 3721 | { | 3721 | { |
| 3722 | struct sfnt_font_info *info; | 3722 | struct sfnt_font_info *info; |
| 3723 | size_t i; | 3723 | size_t i, index; |
| 3724 | int n; | 3724 | int n; |
| 3725 | struct sfnt_mapped_variation_selector_record *record; | 3725 | struct sfnt_mapped_variation_selector_record *record; |
| 3726 | sfnt_glyph default_glyph; | ||
| 3726 | 3727 | ||
| 3727 | info = (struct sfnt_font_info *) font; | 3728 | info = (struct sfnt_font_info *) font; |
| 3728 | n = 0; | 3729 | n = 0; |
| @@ -3743,12 +3744,37 @@ sfntfont_get_variation_glyphs (struct font *font, int c, | |||
| 3743 | && info->uvs->records[i].selector < 0xfe00) | 3744 | && info->uvs->records[i].selector < 0xfe00) |
| 3744 | ++i; | 3745 | ++i; |
| 3745 | 3746 | ||
| 3747 | /* Get the glyph represented by C, used when C is present within a | ||
| 3748 | default value table. */ | ||
| 3749 | |||
| 3750 | default_glyph = sfntfont_lookup_glyph (info, c); | ||
| 3751 | |||
| 3746 | /* Fill in selectors 0 to 15. */ | 3752 | /* Fill in selectors 0 to 15. */ |
| 3747 | 3753 | ||
| 3748 | while (i < info->uvs->num_records | 3754 | while (i < info->uvs->num_records |
| 3749 | && info->uvs->records[i].selector <= 0xfe0f) | 3755 | && info->uvs->records[i].selector <= 0xfe0f) |
| 3750 | { | 3756 | { |
| 3751 | record = &info->uvs->records[i]; | 3757 | record = &info->uvs->records[i]; |
| 3758 | index = info->uvs->records[i].selector - 0xfe00 + 16; | ||
| 3759 | |||
| 3760 | /* Handle invalid unsorted tables. */ | ||
| 3761 | |||
| 3762 | if (record->selector < 0xfe00) | ||
| 3763 | return 0; | ||
| 3764 | |||
| 3765 | /* If there are default mappings in this record, ascertain if | ||
| 3766 | this glyph matches one of them. */ | ||
| 3767 | |||
| 3768 | if (record->default_uvs | ||
| 3769 | && sfnt_is_character_default (record->default_uvs, c)) | ||
| 3770 | { | ||
| 3771 | variations[index] = default_glyph; | ||
| 3772 | |||
| 3773 | if (default_glyph) | ||
| 3774 | ++n; | ||
| 3775 | |||
| 3776 | goto next_selector; | ||
| 3777 | } | ||
| 3752 | 3778 | ||
| 3753 | /* If record has no non-default mappings, continue on to the | 3779 | /* If record has no non-default mappings, continue on to the |
| 3754 | next selector. */ | 3780 | next selector. */ |
| @@ -3756,18 +3782,13 @@ sfntfont_get_variation_glyphs (struct font *font, int c, | |||
| 3756 | if (!record->nondefault_uvs) | 3782 | if (!record->nondefault_uvs) |
| 3757 | goto next_selector; | 3783 | goto next_selector; |
| 3758 | 3784 | ||
| 3759 | /* Handle invalid unsorted tables. */ | ||
| 3760 | |||
| 3761 | if (record->selector < 0xfe00) | ||
| 3762 | return 0; | ||
| 3763 | |||
| 3764 | /* Find the glyph ID associated with C and put it in | 3785 | /* Find the glyph ID associated with C and put it in |
| 3765 | VARIATIONS. */ | 3786 | VARIATIONS. */ |
| 3766 | 3787 | ||
| 3767 | variations[info->uvs->records[i].selector - 0xfe00] | 3788 | variations[index] |
| 3768 | = sfnt_variation_glyph_for_char (record->nondefault_uvs, c); | 3789 | = sfnt_variation_glyph_for_char (record->nondefault_uvs, c); |
| 3769 | 3790 | ||
| 3770 | if (variations[info->uvs->records[i].selector - 0xfe00]) | 3791 | if (variations[index]) |
| 3771 | ++n; | 3792 | ++n; |
| 3772 | 3793 | ||
| 3773 | next_selector: | 3794 | next_selector: |
| @@ -3787,6 +3808,26 @@ sfntfont_get_variation_glyphs (struct font *font, int c, | |||
| 3787 | && info->uvs->records[i].selector <= 0xe01ef) | 3808 | && info->uvs->records[i].selector <= 0xe01ef) |
| 3788 | { | 3809 | { |
| 3789 | record = &info->uvs->records[i]; | 3810 | record = &info->uvs->records[i]; |
| 3811 | index = info->uvs->records[i].selector - 0xe0100 + 16; | ||
| 3812 | |||
| 3813 | /* Handle invalid unsorted tables. */ | ||
| 3814 | |||
| 3815 | if (record->selector < 0xe0100) | ||
| 3816 | return 0; | ||
| 3817 | |||
| 3818 | /* If there are default mappings in this record, ascertain if | ||
| 3819 | this glyph matches one of them. */ | ||
| 3820 | |||
| 3821 | if (record->default_uvs | ||
| 3822 | && sfnt_is_character_default (record->default_uvs, c)) | ||
| 3823 | { | ||
| 3824 | variations[index] = default_glyph; | ||
| 3825 | |||
| 3826 | if (default_glyph) | ||
| 3827 | ++n; | ||
| 3828 | |||
| 3829 | goto next_selector_1; | ||
| 3830 | } | ||
| 3790 | 3831 | ||
| 3791 | /* If record has no non-default mappings, continue on to the | 3832 | /* If record has no non-default mappings, continue on to the |
| 3792 | next selector. */ | 3833 | next selector. */ |
| @@ -3794,18 +3835,13 @@ sfntfont_get_variation_glyphs (struct font *font, int c, | |||
| 3794 | if (!record->nondefault_uvs) | 3835 | if (!record->nondefault_uvs) |
| 3795 | goto next_selector_1; | 3836 | goto next_selector_1; |
| 3796 | 3837 | ||
| 3797 | /* Handle invalid unsorted tables. */ | ||
| 3798 | |||
| 3799 | if (record->selector < 0xe0100) | ||
| 3800 | return 0; | ||
| 3801 | |||
| 3802 | /* Find the glyph ID associated with C and put it in | 3838 | /* Find the glyph ID associated with C and put it in |
| 3803 | VARIATIONS. */ | 3839 | VARIATIONS. */ |
| 3804 | 3840 | ||
| 3805 | variations[info->uvs->records[i].selector - 0xe0100 + 16] | 3841 | variations[index] |
| 3806 | = sfnt_variation_glyph_for_char (record->nondefault_uvs, c); | 3842 | = sfnt_variation_glyph_for_char (record->nondefault_uvs, c); |
| 3807 | 3843 | ||
| 3808 | if (variations[info->uvs->records[i].selector - 0xe0100 + 16]) | 3844 | if (variations[index]) |
| 3809 | ++n; | 3845 | ++n; |
| 3810 | 3846 | ||
| 3811 | next_selector_1: | 3847 | next_selector_1: |
| @@ -3841,7 +3877,7 @@ sfntfont_detect_sigbus (void *addr) | |||
| 3841 | return false; | 3877 | return false; |
| 3842 | } | 3878 | } |
| 3843 | 3879 | ||
| 3844 | #endif | 3880 | #endif /* HAVE_MMAP */ |
| 3845 | 3881 | ||
| 3846 | 3882 | ||
| 3847 | 3883 | ||