From 2e6038a209022c8b7957daf661488edfc166bdc5 Mon Sep 17 00:00:00 2001 From: Michiharu Ariza Date: Tue, 19 Mar 2019 00:41:41 -0700 Subject: [PATCH] add api tests for subset gvar & HVAR; bug fixes --- src/hb-ot-layout-common.hh | 3 +- src/hb-ot-var-gvar-table.hh | 24 +++--- src/hb-ot-var-hvar-table.hh | 19 +++- test/api/Makefile.am | 2 + .../fonts/SourceSansVariable-Roman.abc.ttf | Bin 0 -> 3240 bytes .../api/fonts/SourceSansVariable-Roman.ac.ttf | Bin 0 -> 3028 bytes test/api/test-subset-gvar.c | 81 ++++++++++++++++++ test/api/test-subset-hvar.c | 81 ++++++++++++++++++ 8 files changed, 194 insertions(+), 16 deletions(-) create mode 100644 test/api/fonts/SourceSansVariable-Roman.abc.ttf create mode 100644 test/api/fonts/SourceSansVariable-Roman.ac.ttf create mode 100644 test/api/test-subset-gvar.c create mode 100644 test/api/test-subset-hvar.c diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index a82e2d95d..fe4d78c41 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -1757,7 +1757,8 @@ struct VarData shortCount.set (src->shortCount); unsigned int row_size = src->get_row_size (); - if (unlikely (!c->allocate_size (src->regionIndices.get_size () + (row_size * remap.get_count ())))) + unsigned int size = src->regionIndices.get_size () - HBUINT16::static_size/*regionIndices.len*/ + (row_size * remap.get_count ()); + if (unlikely (!c->allocate_size (size))) return_trace (false); memcpy (®ionIndices, &src->regionIndices, src->regionIndices.get_size ()); diff --git a/src/hb-ot-var-gvar-table.hh b/src/hb-ot-var-gvar-table.hh index 77454dcd9..50797bdcd 100644 --- a/src/hb-ot-var-gvar-table.hh +++ b/src/hb-ot-var-gvar-table.hh @@ -422,6 +422,18 @@ struct gvar HBUINT8 *subset_offsets = c->serializer->allocate_size ((long_offset? 4: 2) * (num_glyphs+1)); if (!subset_offsets) return_trace (false); + /* shared tuples */ + if (!sharedTupleCount || !sharedTuples) + out->sharedTuples.set (0); + else + { + unsigned int shared_tuple_size = F2DOT14::static_size * axisCount * sharedTupleCount; + F2DOT14 *tuples = c->serializer->allocate_size (shared_tuple_size); + if (!tuples) return_trace (false); + out->sharedTuples.set ((char *)tuples - (char *)out); + memcpy (tuples, &(this+sharedTuples), shared_tuple_size); + } + char *subset_data = c->serializer->allocate_size(subset_data_size); if (!subset_data) return_trace (false); out->dataZ.set (subset_data - (char *)out); @@ -446,18 +458,6 @@ struct gvar else ((HBUINT16 *)subset_offsets)[num_glyphs].set (glyph_offset / 2); - /* shared tuples */ - if (!sharedTupleCount || !sharedTuples) - out->sharedTuples.set (0); - else - { - unsigned int shared_tuple_size = F2DOT14::static_size * axisCount * sharedTupleCount; - F2DOT14 *tuples = c->serializer->allocate_size (shared_tuple_size); - if (!tuples) return_trace (false); - out->sharedTuples.set ((char *)tuples - (char *)out); - memcpy (tuples, &(this+sharedTuples), shared_tuple_size); - } - return_trace (true); } diff --git a/src/hb-ot-var-hvar-table.hh b/src/hb-ot-var-hvar-table.hh index 21d6b765b..e349e7a52 100644 --- a/src/hb-ot-var-hvar-table.hh +++ b/src/hb-ot-var-hvar-table.hh @@ -134,7 +134,14 @@ struct index_map_subset_plan_t /* Identity map */ if (&index_map == &Null(DeltaSetIndexMap)) + { + outer_remap.add (0); + hb_codepoint_t old_gid; + for (hb_codepoint_t gid = 0; gid < plan->num_output_glyphs (); gid++) + if (plan->old_gid_for_new_gid (gid, &old_gid)) + inner_remaps[0].add (old_gid); return; + } unsigned int last_val = (unsigned int)-1; hb_codepoint_t last_gid = (hb_codepoint_t)-1; @@ -189,6 +196,11 @@ struct index_map_subset_plan_t const hb_bimap_t &outer_remap, const hb_vector_t &inner_remaps) { + /* Leave output_map empty for an identity map */ + /* TODO: if retain_gids, convert identity to a customized map, or not subset varstore? */ + if (input_map == &Null(DeltaSetIndexMap)) + return; + for (unsigned int i = 0; i < max_inners.length; i++) { if (inner_remaps[i].get_count () == 0) continue; @@ -214,6 +226,7 @@ struct index_map_subset_plan_t unsigned int get_size () const { return (map_count? (DeltaSetIndexMap::min_size + get_width () * map_count): 0); } + bool is_identity () const { return get_output_map ().length == 0; } hb_array_t get_output_map () const { return output_map.as_array (); } protected: @@ -311,15 +324,15 @@ struct HVARVVAR const hb_array_t &im_plans) { TRACE_SUBSET (this); - if (!im_plans[ADV_INDEX].get_map_count ()) + if (im_plans[ADV_INDEX].is_identity ()) advMap.set (0); else if (unlikely (!advMap.serialize (c, this).serialize (c, im_plans[ADV_INDEX]))) return_trace (false); - if (!im_plans[LSB_INDEX].get_map_count ()) + if (im_plans[LSB_INDEX].is_identity ()) lsbMap.set (0); else if (unlikely (!lsbMap.serialize (c, this).serialize (c, im_plans[LSB_INDEX]))) return_trace (false); - if (!im_plans[RSB_INDEX].get_map_count ()) + if (im_plans[RSB_INDEX].is_identity ()) rsbMap.set (0); else if (unlikely (!rsbMap.serialize (c, this).serialize (c, im_plans[RSB_INDEX]))) return_trace (false); diff --git a/test/api/Makefile.am b/test/api/Makefile.am index 0f3dab73a..846b00ac4 100644 --- a/test/api/Makefile.am +++ b/test/api/Makefile.am @@ -50,6 +50,8 @@ TEST_PROGS = \ test-subset-vmtx \ test-subset-cff1 \ test-subset-cff2 \ + test-subset-gvar \ + test-subset-hvar \ test-unicode \ test-version \ $(NULL) diff --git a/test/api/fonts/SourceSansVariable-Roman.abc.ttf b/test/api/fonts/SourceSansVariable-Roman.abc.ttf new file mode 100644 index 0000000000000000000000000000000000000000..690d7d5392e21dc9ad01b86dfbe35ce8591c02ac GIT binary patch literal 3240 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 literal 0 HcmV?d00001 diff --git a/test/api/test-subset-gvar.c b/test/api/test-subset-gvar.c new file mode 100644 index 000000000..84cd48394 --- /dev/null +++ b/test/api/test-subset-gvar.c @@ -0,0 +1,81 @@ +/* + * Copyright © 2019 Adobe Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Adobe Author(s): Michiharu Ariza + */ + +#include "hb-test.h" +#include "hb-subset-test.h" + +/* Unit tests for gvar subsetting */ + +static void +test_subset_gvar_noop (void) +{ + hb_face_t *face_abc = hb_test_open_font_file("fonts/SourceSansVariable-Roman.abc.ttf"); + + hb_set_t *codepoints = hb_set_create (); + hb_face_t *face_abc_subset; + hb_set_add (codepoints, 'a'); + hb_set_add (codepoints, 'b'); + hb_set_add (codepoints, 'c'); + face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints)); + hb_set_destroy (codepoints); + + hb_subset_test_check (face_abc, face_abc_subset, HB_TAG ('g','v','a','r')); + + hb_face_destroy (face_abc_subset); + hb_face_destroy (face_abc); +} + +static void +test_subset_gvar (void) +{ + hb_face_t *face_abc = hb_test_open_font_file ("fonts/SourceSansVariable-Roman.abc.ttf"); + hb_face_t *face_ac = hb_test_open_font_file ("fonts/SourceSansVariable-Roman.ac.ttf"); + + hb_set_t *codepoints = hb_set_create (); + hb_face_t *face_abc_subset; + hb_set_add (codepoints, 'a'); + hb_set_add (codepoints, 'c'); + face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints)); + hb_set_destroy (codepoints); + + hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('g','v','a','r')); + + hb_face_destroy (face_abc_subset); + hb_face_destroy (face_abc); + hb_face_destroy (face_ac); +} + + +int +main (int argc, char **argv) +{ + hb_test_init (&argc, &argv); + + hb_test_add (test_subset_gvar_noop); + hb_test_add (test_subset_gvar); + + return hb_test_run (); +} diff --git a/test/api/test-subset-hvar.c b/test/api/test-subset-hvar.c new file mode 100644 index 000000000..0e60cc932 --- /dev/null +++ b/test/api/test-subset-hvar.c @@ -0,0 +1,81 @@ +/* + * Copyright © 2019 Adobe Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Adobe Author(s): Michiharu Ariza + */ + +#include "hb-test.h" +#include "hb-subset-test.h" + +/* Unit tests for HVAR subsetting */ + +static void +test_subset_HVAR_noop (void) +{ + hb_face_t *face_abc = hb_test_open_font_file("fonts/SourceSansVariable-Roman.abc.ttf"); + + hb_set_t *codepoints = hb_set_create (); + hb_face_t *face_abc_subset; + hb_set_add (codepoints, 'a'); + hb_set_add (codepoints, 'b'); + hb_set_add (codepoints, 'c'); + face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints)); + hb_set_destroy (codepoints); + + hb_subset_test_check (face_abc, face_abc_subset, HB_TAG ('H','V','A','R')); + + hb_face_destroy (face_abc_subset); + hb_face_destroy (face_abc); +} + +static void +test_subset_HVAR (void) +{ + hb_face_t *face_abc = hb_test_open_font_file ("fonts/SourceSansVariable-Roman.abc.ttf"); + hb_face_t *face_ac = hb_test_open_font_file ("fonts/SourceSansVariable-Roman.ac.ttf"); + + hb_set_t *codepoints = hb_set_create (); + hb_face_t *face_abc_subset; + hb_set_add (codepoints, 'a'); + hb_set_add (codepoints, 'c'); + face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints)); + hb_set_destroy (codepoints); + + hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('H','V','A','R')); + + hb_face_destroy (face_abc_subset); + hb_face_destroy (face_abc); + hb_face_destroy (face_ac); +} + + +int +main (int argc, char **argv) +{ + hb_test_init (&argc, &argv); + + hb_test_add (test_subset_HVAR_noop); + hb_test_add (test_subset_HVAR); + + return hb_test_run (); +}