From dadb4ed71de2da768ee4f07a3b595181813fb0f4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 17 Oct 2022 12:48:24 -0600 Subject: [PATCH] [glyf/VarComposite] More, almost there --- src/OT/glyf/Glyph.hh | 18 ++++++---- src/OT/glyf/VarCompositeGlyph.hh | 58 +++++++++++++++++++++++++++----- 2 files changed, 60 insertions(+), 16 deletions(-) diff --git a/src/OT/glyf/Glyph.hh b/src/OT/glyf/Glyph.hh index 8ebdb6124..fda6c191a 100644 --- a/src/OT/glyf/Glyph.hh +++ b/src/OT/glyf/Glyph.hh @@ -261,9 +261,9 @@ struct Glyph case VAR_COMPOSITE: { points.resize (0); - //for (auto &item : get_var_composite_iterator ()) + for (auto &item : get_var_composite_iterator ()) { - /* XXX */ + if (unlikely (!item.get_points (points))) return false; } } default: @@ -376,20 +376,22 @@ struct Glyph case VAR_COMPOSITE: { contour_point_vector_t comp_points; + hb_array_t points_left = points.as_array (); for (auto &item : get_var_composite_iterator ()) { + hb_array_t record_points = points_left.sub_array (0, item.get_num_points ()); + comp_points.reset (); + /* XXX Apply variations. */ + if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_gid ()) .get_points (font, glyf_accelerator, comp_points, deltas, shift_points_hori, use_my_metrics, phantom_only, depth + 1))) return false; - /* Apply component transformation & translation */ - item.transform_points (comp_points); - - /* Apply translation from gvar */ - //comp_points.translate (points[comp_index]); + /* Apply component transformation */ + item.transform_points (record_points, comp_points); /* Copy phantom points from component if USE_MY_METRICS flag set */ if (use_my_metrics && item.is_use_my_metrics ()) @@ -397,6 +399,8 @@ struct Glyph phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i]; all_points.extend (comp_points.sub_array (0, comp_points.length - PHANTOM_COUNT)); + + points_left += item.get_num_points (); } all_points.extend (phantoms); } break; diff --git a/src/OT/glyf/VarCompositeGlyph.hh b/src/OT/glyf/VarCompositeGlyph.hh index cf4a3f931..86f291ac2 100644 --- a/src/OT/glyf/VarCompositeGlyph.hh +++ b/src/OT/glyf/VarCompositeGlyph.hh @@ -71,12 +71,13 @@ struct VarCompositeGlyphRecord return num_axes + NUM_TRANSFORM_POINTS; } - void transform_points (contour_point_vector_t &points) const + void transform_points (hb_array_t transformation_points, + contour_point_vector_t &points) const { float matrix[4]; contour_point_t trans; - get_transformation (matrix, trans); + get_transformation_from_points (transformation_points, matrix, trans); points.transform (matrix); points.translate (trans); @@ -144,7 +145,7 @@ struct VarCompositeGlyphRecord transform (matrix, trans, other); } - void get_transformation (float (&matrix)[4], contour_point_t &trans) const + bool get_points (contour_point_vector_t &points) const { float translateX = 0.f; float translateY = 0.f; @@ -156,28 +157,67 @@ struct VarCompositeGlyphRecord float tCenterX = 0.f; float tCenterY = 0.f; - unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 4 : 3; + if (unlikely (!points.resize (points.length + get_num_points ()))) return false; + + unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 2 : 1; unsigned axes_size = num_axes * axis_width; - const HBUINT16 *p = (const HBUINT16 *) (axes_size + - &StructAfter (num_axes)); + + const F2DOT14 *q = (const F2DOT14 *) (axes_size + + &StructAfter (num_axes)); + + hb_array_t axis_points = points.sub_array (points.length - get_num_points ()); + unsigned count = num_axes; + for (unsigned i = 0; i < count; i++) + axis_points[i].x = *q++; + + const HBUINT16 *p = (const HBUINT16 *) q; if (flags & HAVE_TRANSLATE_X) translateX = * (const FWORD *) p++; if (flags & HAVE_TRANSLATE_Y) translateY = * (const FWORD *) p++; - if (flags & HAVE_ROTATION) rotation = (* (const F2DOT14 *) p++).to_float (); + if (flags & HAVE_ROTATION) rotation = * (const F2DOT14 *) p++; if (flags & HAVE_SCALE_X) scaleX = * (const F4DOT12 *) p++; if (flags & HAVE_SCALE_Y) scaleY = * (const F4DOT12 *) p++; - if (flags & HAVE_SKEW_X) skewX = (* (const F2DOT14 *) p++).to_float (); - if (flags & HAVE_SKEW_Y) skewY = (* (const F2DOT14 *) p++).to_float (); + if (flags & HAVE_SKEW_X) skewX = * (const F2DOT14 *) p++; + if (flags & HAVE_SKEW_Y) skewY = * (const F2DOT14 *) p++; if (flags & HAVE_TCENTER_X) tCenterX = * (const FWORD *) p++; if (flags & HAVE_TCENTER_Y) tCenterY = * (const FWORD *) p++; if ((flags & UNIFORM_SCALE) && !(flags & HAVE_SCALE_Y)) scaleY = scaleX; + hb_array_t t = points.sub_array (points.length - NUM_TRANSFORM_POINTS); + t[0].x = translateX; + t[0].y = translateY; + t[1].x = rotation; + t[2].x = scaleX; + t[2].y = scaleY; + t[3].x = skewX; + t[3].y = skewY; + t[4].x = tCenterX; + t[4].y = tCenterY; + + return true; + } + + void get_transformation_from_points (hb_array_t points, + float (&matrix)[4], contour_point_t &trans) const + { matrix[0] = matrix[3] = 1.f; matrix[1] = matrix[2] = 0.f; trans.init (0.f, 0.f); + hb_array_t t = points.sub_array (points.length - NUM_TRANSFORM_POINTS); + + float translateX = t[0].x; + float translateY = t[0].y; + float rotation = t[1].x / (1 << 14); + float scaleX = t[2].x / (1 << 12); + float scaleY = t[2].y / (1 << 12); + float skewX = t[3].x / (1 << 14); + float skewY = t[3].y / (1 << 14); + float tCenterX = t[4].x; + float tCenterY = t[4].y; + translate (matrix, trans, translateX + tCenterX, translateY + tCenterY); rotate (matrix, trans, rotation); scale (matrix, trans, scaleX, scaleY);