From 3520f528aaba200ab2e3f1edfe746c7963a7ce54 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 21 Apr 2023 15:46:36 -0600 Subject: [PATCH] [CompositeGlyph] Apply gvar deltas with component transform This was being done wrong for one of the scaled_offsets() cases. --- src/OT/glyf/CompositeGlyph.hh | 37 +++++++++++++++++++++-------------- src/OT/glyf/Glyph.hh | 14 ++++++------- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/OT/glyf/CompositeGlyph.hh b/src/OT/glyf/CompositeGlyph.hh index f43dd2239..f599e1f7f 100644 --- a/src/OT/glyf/CompositeGlyph.hh +++ b/src/OT/glyf/CompositeGlyph.hh @@ -87,25 +87,32 @@ struct CompositeGlyphRecord } } - void transform_points (contour_point_vector_t &points) const + void transform_points (contour_point_vector_t &points, + const float (&matrix)[4], + const contour_point_t &trans) const { - float matrix[4]; - contour_point_t trans; - if (get_transformation (matrix, trans)) + if (scaled_offsets ()) { - if (scaled_offsets ()) - { - points.translate (trans); - points.transform (matrix); - } - else - { - points.transform (matrix); - points.translate (trans); - } + points.translate (trans); + points.transform (matrix); + } + else + { + points.transform (matrix); + points.translate (trans); } } + bool get_points (contour_point_vector_t &points) const + { + float matrix[4]; + contour_point_t trans; + get_transformation (matrix, trans); + if (unlikely (!points.resize (points.length + 1))) return false; + points[points.length - 1] = trans; + return true; + } + unsigned compile_with_deltas (const contour_point_t &p_delta, char *out) const { @@ -171,6 +178,7 @@ struct CompositeGlyphRecord bool scaled_offsets () const { return (flags & (SCALED_COMPONENT_OFFSET | UNSCALED_COMPONENT_OFFSET)) == SCALED_COMPONENT_OFFSET; } + public: bool get_transformation (float (&matrix)[4], contour_point_t &trans) const { matrix[0] = matrix[3] = 1.f; @@ -225,7 +233,6 @@ struct CompositeGlyphRecord return tx || ty; } - public: hb_codepoint_t get_gid () const { #ifndef HB_NO_BEYOND_64K diff --git a/src/OT/glyf/Glyph.hh b/src/OT/glyf/Glyph.hh index c9c0de45e..29b49389c 100644 --- a/src/OT/glyf/Glyph.hh +++ b/src/OT/glyf/Glyph.hh @@ -320,9 +320,8 @@ struct Glyph break; case COMPOSITE: { - /* pseudo component points for each component in composite glyph */ - unsigned num_points = hb_len (CompositeGlyph (*header, bytes).iter ()); - if (unlikely (!points.resize (num_points))) return false; + for (auto &item : get_composite_iterator ()) + if (unlikely (!item.get_points (points))) return false; break; } #ifndef HB_NO_VAR_COMPOSITES @@ -422,11 +421,12 @@ struct Glyph for (unsigned int i = 0; i < PHANTOM_COUNT; i++) phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i]; - /* Apply component transformation & translation */ - item.transform_points (comp_points); + float matrix[4]; + contour_point_t default_trans; + item.get_transformation (matrix, default_trans); - /* Apply translation from gvar */ - comp_points.translate (points[comp_index]); + /* Apply component transformation & translation (with deltas applied) */ + item.transform_points (comp_points, matrix, points[comp_index]); if (item.is_anchored ()) {