diff --git a/src/hb-ot-hdmx-table.hh b/src/hb-ot-hdmx-table.hh index c523c420a..87dd6d018 100644 --- a/src/hb-ot-hdmx-table.hh +++ b/src/hb-ot-hdmx-table.hh @@ -88,8 +88,13 @@ struct DeviceRecord { TRACE_SERIALIZE (this); - if (unlikely (!c->allocate_size (get_size (subset_view.len())))) + unsigned int size = get_size (subset_view.len()); + if (unlikely (!c->allocate_size (size))) + { + DEBUG_MSG (SUBSET, nullptr, "Couldn't allocate enough space for DeviceRecord: %d.", + size); return_trace (false); + } this->pixel_size.set (subset_view.source_device_record->pixel_size); this->max_width.set (subset_view.source_device_record->max_width); @@ -160,14 +165,14 @@ struct hdmx return_trace (true); } - static inline size_t get_subsetted_size (hb_subset_plan_t *plan) + static inline size_t get_subsetted_size (const hdmx *source_hdmx, hb_subset_plan_t *plan) { - return min_size + DeviceRecord::get_size (plan->glyphs.len); + return min_size + source_hdmx->num_records * DeviceRecord::get_size (plan->glyphs.len); } inline bool subset (hb_subset_plan_t *plan) const { - size_t dest_size = get_subsetted_size (plan); + size_t dest_size = get_subsetted_size (this, plan); hdmx *dest = (hdmx *) malloc (dest_size); if (unlikely (!dest)) { @@ -180,6 +185,7 @@ struct hdmx if (!hdmx_prime || !hdmx_prime->serialize (&c, this, plan)) { free (dest); + DEBUG_MSG(SUBSET, nullptr, "Failed to serialize write new hdmx."); return false; } c.end_serialize (); diff --git a/test/api/fonts/Roboto-Regular.multihdmx.a.ttf b/test/api/fonts/Roboto-Regular.multihdmx.a.ttf new file mode 100644 index 000000000..dd82178fd Binary files /dev/null and b/test/api/fonts/Roboto-Regular.multihdmx.a.ttf differ diff --git a/test/api/fonts/Roboto-Regular.multihdmx.abc.ttf b/test/api/fonts/Roboto-Regular.multihdmx.abc.ttf new file mode 100644 index 000000000..03dd8b6b7 Binary files /dev/null and b/test/api/fonts/Roboto-Regular.multihdmx.abc.ttf differ diff --git a/test/api/test-subset-hdmx.c b/test/api/test-subset-hdmx.c index 22fcb4118..8a1e821a3 100644 --- a/test/api/test-subset-hdmx.c +++ b/test/api/test-subset-hdmx.c @@ -50,6 +50,25 @@ test_subset_hdmx_simple_subset (void) hb_face_destroy (face_ac); } +static void +test_subset_hdmx_multiple_device_records (void) +{ + hb_face_t *face_abc = hb_subset_test_open_font ("fonts/Roboto-Regular.multihdmx.abc.ttf"); + hb_face_t *face_a = hb_subset_test_open_font ("fonts/Roboto-Regular.multihdmx.a.ttf"); + + hb_set_t *codepoints = hb_set_create (); + hb_face_t *face_abc_subset; + hb_set_add (codepoints, 'a'); + 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_a, face_abc_subset, HB_TAG ('h','d','m','x')); + + hb_face_destroy (face_abc_subset); + hb_face_destroy (face_abc); + hb_face_destroy (face_a); +} + static void test_subset_hdmx_invalid (void) { @@ -115,6 +134,7 @@ main (int argc, char **argv) hb_test_init (&argc, &argv); hb_test_add (test_subset_hdmx_simple_subset); + hb_test_add (test_subset_hdmx_multiple_device_records); hb_test_add (test_subset_hdmx_invalid); hb_test_add (test_subset_hdmx_fails_sanitize); hb_test_add (test_subset_hdmx_noop);