From a9a607d360c491104517bffdb81701c99252cfe4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 22 Jul 2021 16:49:56 -0700 Subject: [PATCH] [variations] Support multiple axes with same tag, aka HOI The axes in fvar are in arbitrary order, NOT sorted. Hence have to lsearch all entries. Fixes https://github.com/harfbuzz/harfbuzz/issues/1673 Fixes https://github.com/harfbuzz/harfbuzz/issues/2743 Test from https://github.com/ctrlcctrlv/FontForge-Higher-Order-Interpolation --- src/hb-font.cc | 21 +++++++------ src/hb-ot-var-fvar-table.hh | 29 ++---------------- test/shaping/data/in-house/Makefile.sources | 3 +- ...691822f6a705e3e9fb48a0405c645b1a036590.ttf | Bin 0 -> 2192 bytes test/shaping/data/in-house/meson.build | 3 +- .../in-house/tests/variations-rounding.tests | 2 -- .../in-house/tests/variations-space.tests | 2 -- .../data/in-house/tests/variations.tests | 5 +++ 8 files changed, 21 insertions(+), 44 deletions(-) create mode 100644 test/shaping/data/in-house/fonts/e8691822f6a705e3e9fb48a0405c645b1a036590.ttf delete mode 100644 test/shaping/data/in-house/tests/variations-rounding.tests delete mode 100644 test/shaping/data/in-house/tests/variations-space.tests create mode 100644 test/shaping/data/in-house/tests/variations.tests diff --git a/src/hb-font.cc b/src/hb-font.cc index a0971b27d..fa8da9639 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -2052,7 +2052,9 @@ hb_font_set_variations (hb_font_t *font, return; } - unsigned int coords_length = hb_ot_var_get_axis_count (font->face); + const OT::fvar &fvar = *font->face->table.fvar; + auto axes = fvar.get_axes (); + const unsigned coords_length = axes.length; int *normalized = coords_length ? (int *) hb_calloc (coords_length, sizeof (int)) : nullptr; float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr; @@ -2064,17 +2066,16 @@ hb_font_set_variations (hb_font_t *font, return; } - const OT::fvar &fvar = *font->face->table.fvar; for (unsigned int i = 0; i < variations_length; i++) { - unsigned axis_index; - if (fvar.find_axis_index (variations[i].tag, &axis_index) && - axis_index < coords_length) - { - float v = variations[i].value; - design_coords[axis_index] = v; - normalized[axis_index] = fvar.normalize_axis_value (axis_index, v); - } + const auto tag = variations[i].tag; + const auto v = variations[i].value; + for (unsigned axis_index = 0; axis_index < coords_length; axis_index++) + if (axes[axis_index].axisTag == tag) + { + design_coords[axis_index] = v; + normalized[axis_index] = fvar.normalize_axis_value (axis_index, v); + } } font->face->table.avar->map_coords (normalized, coords_length); diff --git a/src/hb-ot-var-fvar-table.hh b/src/hb-ot-var-fvar-table.hh index 0f2722199..05f289db2 100644 --- a/src/hb-ot-var-fvar-table.hh +++ b/src/hb-ot-var-fvar-table.hh @@ -213,38 +213,15 @@ struct fvar if (!axis_index) axis_index = &i; *axis_index = HB_OT_VAR_NO_AXIS_INDEX; auto axes = get_axes (); - return find_axis_index (tag, axis_index) && (axes[*axis_index].get_axis_deprecated (info), true); + return axes.lfind (tag, axis_index) && (axes[*axis_index].get_axis_deprecated (info), true); } #endif - - bool - find_axis_index (hb_tag_t tag, - unsigned *axis_index_start, - unsigned *axis_index_end = nullptr) const - { - auto axes = get_axes (); - - /* TODO bfind() for larger array? Should then look back to find first entry for tag. */ - if (!axes.lfind (tag, axis_index_start)) - return false; - - if (axis_index_end) - { - unsigned end = *axis_index_start + 1; - unsigned count = axes.length; - while (end < count && axes[end].axisTag == tag) - end++; - *axis_index_end = end; - } - - return true; - } bool find_axis_info (hb_tag_t tag, hb_ot_var_axis_info_t *info) const { unsigned i; auto axes = get_axes (); - return find_axis_index (tag, &i) && (axes[i].get_axis_info (i, info), true); + return axes.lfind (tag, &i) && (axes[i].get_axis_info (i, info), true); } int normalize_axis_value (unsigned int axis_index, float v) const @@ -313,7 +290,7 @@ struct fvar ; } - protected: + public: hb_array_t get_axes () const { return hb_array (&(this+firstAxis), axisCount); } diff --git a/test/shaping/data/in-house/Makefile.sources b/test/shaping/data/in-house/Makefile.sources index ae48a776a..46e3b5e14 100644 --- a/test/shaping/data/in-house/Makefile.sources +++ b/test/shaping/data/in-house/Makefile.sources @@ -58,9 +58,8 @@ TESTS = \ tests/use-marchen.tests \ tests/use-syllable.tests \ tests/use.tests \ - tests/variations-rounding.tests \ + tests/variations.tests \ tests/variations-rvrn.tests \ - tests/variations-space.tests \ tests/vertical.tests \ tests/zero-width-marks.tests \ $(NULL) diff --git a/test/shaping/data/in-house/fonts/e8691822f6a705e3e9fb48a0405c645b1a036590.ttf b/test/shaping/data/in-house/fonts/e8691822f6a705e3e9fb48a0405c645b1a036590.ttf new file mode 100644 index 0000000000000000000000000000000000000000..7c3a5b1b5a7f27c7453982c22e9d6682b1e6c626 GIT binary patch literal 2192 zcmc&!O-x)>6#m|QGgC^NmKGc$Y2XzQYcr|CfCCCNGsQvb0Aqku)CM{orUN(>1T?_H zK(y7MQ4|+wShX&Uo0=$ze+yTJ#FYt&Q4<$RV(YFz7p<1(ckX+^2^tety*KBc|L>gp z-gyrOfPkG0?s6yRB-)!%w1+8Mppe1-a7)E5$64~P27o=XF&lKQ!>?r8VI z()=fYcbEEQjKRc32B8)cbpHa^nPEL-( z2li&XN8P%Z98L$8pZtOO-_UkvbYy(OzJX@mNAQmk_PD*FQYwfNlmibOEmbw4a9zy- zRZ)IIJyLs;s^9NDT2)n1?(?bC)*-W@um0pvaeF~WHqtbh2n5KJ2F$y=~=u)JWCRK!!fMey+bNY5VXN)T+Dy5{z(z2sof0_5Xm z$@1)_%vo_|0|9D|UEu&$UD?Db{OZacG#Ztz>_v%j&Xs-t8)9zw0yfJjv5O zKzIKryLSj^qTIx;g~~{AZ{olAD{(cgrbx1dZ_Bg#e)k}8{R{5TUCNPXB3PM?-@SbI fHIi)M+w!b_lJR?&T=Ew8J1*tOGZA}e_U*p`iwNpT literal 0 HcmV?d00001 diff --git a/test/shaping/data/in-house/meson.build b/test/shaping/data/in-house/meson.build index c98a90de6..f3fe8735b 100644 --- a/test/shaping/data/in-house/meson.build +++ b/test/shaping/data/in-house/meson.build @@ -58,9 +58,8 @@ in_house_tests = [ 'use-marchen.tests', 'use-syllable.tests', 'use.tests', - 'variations-rounding.tests', + 'variations.tests', 'variations-rvrn.tests', - 'variations-space.tests', 'vertical.tests', 'zero-width-marks.tests', ] diff --git a/test/shaping/data/in-house/tests/variations-rounding.tests b/test/shaping/data/in-house/tests/variations-rounding.tests deleted file mode 100644 index 9a03e4fe6..000000000 --- a/test/shaping/data/in-house/tests/variations-rounding.tests +++ /dev/null @@ -1,2 +0,0 @@ -../fonts/HBTest-VF.ttf:--variations=TEST=491:U+0041:[A=0+496] -../fonts/HBTest-VF.ttf:--variations=TEST=509:U+0041:[A=0+505] diff --git a/test/shaping/data/in-house/tests/variations-space.tests b/test/shaping/data/in-house/tests/variations-space.tests deleted file mode 100644 index b5b5deb28..000000000 --- a/test/shaping/data/in-house/tests/variations-space.tests +++ /dev/null @@ -1,2 +0,0 @@ -../fonts/ab40c89624a6104e5d0a2308e448a989302f515b.ttf:--variations=wdth=60:U+0020:[space=0+266] -../fonts/ab40c89624a6104e5d0a2308e448a989302f515b.ttf:--variations=wdth=402:U+0020:[space=0+639] diff --git a/test/shaping/data/in-house/tests/variations.tests b/test/shaping/data/in-house/tests/variations.tests new file mode 100644 index 000000000..a79169e80 --- /dev/null +++ b/test/shaping/data/in-house/tests/variations.tests @@ -0,0 +1,5 @@ +../fonts/HBTest-VF.ttf:--variations=TEST=491:U+0041:[A=0+496] +../fonts/HBTest-VF.ttf:--variations=TEST=509:U+0041:[A=0+505] +../fonts/ab40c89624a6104e5d0a2308e448a989302f515b.ttf:--variations=wdth=60:U+0020:[space=0+266] +../fonts/ab40c89624a6104e5d0a2308e448a989302f515b.ttf:--variations=wdth=402:U+0020:[space=0+639] +../fonts/e8691822f6a705e3e9fb48a0405c645b1a036590.ttf:--variations=0001=500:U+002E,U+0065:[period=0+681|e=1+650]