aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2023-10-22 09:06:28 +0800
committerPo Lu2023-10-22 09:06:28 +0800
commit6f87ee0e3a0727e16079778a4264e6e35cd7f3a8 (patch)
treeaf64e5249371cb4c7e44b13e426c177181cadc60 /src
parent8c15515b62cacae06dd3ced6492142ce185e5adb (diff)
downloademacs-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.c59
-rw-r--r--src/sfnt.h6
-rw-r--r--src/sfntfont.c68
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
12722static int
12723sfnt_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
12762TEST_STATIC bool
12763sfnt_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
19191sfnt_test_uvs (int fd, struct sfnt_cmap_format_14 *format14) 19226sfnt_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
1531extern 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