diff options
Diffstat (limited to 'thirdparty/harfbuzz/src/OT/glyf')
-rw-r--r-- | thirdparty/harfbuzz/src/OT/glyf/Glyph.hh | 66 | ||||
-rw-r--r-- | thirdparty/harfbuzz/src/OT/glyf/SimpleGlyph.hh | 26 | ||||
-rw-r--r-- | thirdparty/harfbuzz/src/OT/glyf/SubsetGlyph.hh | 1 | ||||
-rw-r--r-- | thirdparty/harfbuzz/src/OT/glyf/glyf.hh | 75 |
4 files changed, 97 insertions, 71 deletions
diff --git a/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh b/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh index afcb5dc834..0b25659acc 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh @@ -102,17 +102,19 @@ struct Glyph hb_bytes_t &dest_bytes /* OUT */) const { GlyphHeader *glyph_header = nullptr; - if (all_points.length > 4) + if (type != EMPTY && all_points.length > 4) { glyph_header = (GlyphHeader *) hb_calloc (1, GlyphHeader::static_size); if (unlikely (!glyph_header)) return false; } - int xMin, xMax; - xMin = xMax = roundf (all_points[0].x); - - int yMin, yMax; - yMin = yMax = roundf (all_points[0].y); + int xMin = 0, xMax = 0; + int yMin = 0, yMax = 0; + if (all_points.length > 4) + { + xMin = xMax = roundf (all_points[0].x); + yMin = yMax = roundf (all_points[0].y); + } for (unsigned i = 1; i < all_points.length - 4; i++) { @@ -128,7 +130,7 @@ struct Glyph /*for empty glyphs: all_points only include phantom points. *just update metrics and then return */ - if (all_points.length == 4) + if (!glyph_header) return true; glyph_header->numberOfContours = header->numberOfContours; @@ -145,10 +147,17 @@ struct Glyph hb_font_t *font, const glyf_accelerator_t &glyf, hb_bytes_t &dest_start, /* IN/OUT */ - hb_bytes_t &dest_end /* OUT */) const + hb_bytes_t &dest_end /* OUT */) { contour_point_vector_t all_points, deltas; - get_points (font, glyf, all_points, &deltas, false); + if (!get_points (font, glyf, all_points, &deltas, false, false)) + return false; + + // .notdef, set type to empty so we only update metrics and don't compile bytes for + // it + if (gid == 0 && + !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) + type = EMPTY; switch (type) { case COMPOSITE: @@ -171,7 +180,12 @@ struct Glyph break; } - return compile_header_bytes (plan, all_points, dest_start); + if (!compile_header_bytes (plan, all_points, dest_start)) + { + dest_end.fini (); + return false; + } + return true; } @@ -182,6 +196,7 @@ struct Glyph bool get_points (hb_font_t *font, const accelerator_t &glyf_accelerator, contour_point_vector_t &all_points /* OUT */, contour_point_vector_t *deltas = nullptr, /* OUT */ + bool shift_points_hori = true, bool use_my_metrics = true, bool phantom_only = false, unsigned int depth = 0) const @@ -238,8 +253,7 @@ struct Glyph if (deltas != nullptr && depth == 0 && type == COMPOSITE) { if (unlikely (!deltas->resize (points.length))) return false; - for (unsigned i = 0 ; i < points.length; i++) - deltas->arrayZ[i] = points.arrayZ[i]; + deltas->copy_vector (points); } #ifndef HB_NO_VAR @@ -271,14 +285,9 @@ struct Glyph comp_points.reset (); if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_gid ()) .get_points (font, glyf_accelerator, comp_points, - deltas, use_my_metrics, phantom_only, depth + 1))) + deltas, shift_points_hori, use_my_metrics, phantom_only, depth + 1))) return false; - /* Copy phantom points from component if USE_MY_METRICS flag set */ - if (use_my_metrics && item.is_use_my_metrics ()) - 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); @@ -299,6 +308,11 @@ struct Glyph } } + /* Copy phantom points from component if USE_MY_METRICS flag set */ + if (use_my_metrics && item.is_use_my_metrics ()) + for (unsigned int i = 0; i < PHANTOM_COUNT; i++) + phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i]; + all_points.extend (comp_points.sub_array (0, comp_points.length - PHANTOM_COUNT)); comp_index++; @@ -310,7 +324,7 @@ struct Glyph all_points.extend (phantoms); } - if (depth == 0) /* Apply at top level */ + if (depth == 0 && shift_points_hori) /* Apply at top level */ { /* Undocumented rasterizer behavior: * Shift points horizontally by the updated left side bearing @@ -332,10 +346,16 @@ struct Glyph hb_bytes_t get_bytes () const { return bytes; } - Glyph (hb_bytes_t bytes_ = hb_bytes_t (), - hb_codepoint_t gid_ = (hb_codepoint_t) -1) : bytes (bytes_), - header (bytes.as<GlyphHeader> ()), - gid (gid_) + Glyph () : bytes (), + header (bytes.as<GlyphHeader> ()), + gid (-1), + type(EMPTY) + {} + + Glyph (hb_bytes_t bytes_, + hb_codepoint_t gid_ = (unsigned) -1) : bytes (bytes_), + header (bytes.as<GlyphHeader> ()), + gid (gid_) { int num_contours = header->numberOfContours; if (unlikely (num_contours == 0)) type = EMPTY; diff --git a/thirdparty/harfbuzz/src/OT/glyf/SimpleGlyph.hh b/thirdparty/harfbuzz/src/OT/glyf/SimpleGlyph.hh index b99665d6a0..d45f4eb350 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/SimpleGlyph.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/SimpleGlyph.hh @@ -271,31 +271,29 @@ struct SimpleGlyph } //convert absolute values to relative values unsigned num_points = all_points.length - 4; - hb_vector_t<hb_pair_t<int, int>> deltas; - deltas.resize (num_points); - - for (unsigned i = 0; i < num_points; i++) - { - deltas[i].first = i == 0 ? roundf (all_points[i].x) : roundf (all_points[i].x) - roundf (all_points[i-1].x); - deltas[i].second = i == 0 ? roundf (all_points[i].y) : roundf (all_points[i].y) - roundf (all_points[i-1].y); - } hb_vector_t<uint8_t> flags, x_coords, y_coords; - flags.alloc (num_points); - x_coords.alloc (2*num_points); - y_coords.alloc (2*num_points); + if (unlikely (!flags.alloc (num_points))) return false; + if (unlikely (!x_coords.alloc (2*num_points))) return false; + if (unlikely (!y_coords.alloc (2*num_points))) return false; uint8_t lastflag = 0, repeat = 0; - + int prev_x = 0.f, prev_y = 0.f; + for (unsigned i = 0; i < num_points; i++) { uint8_t flag = all_points[i].flag; flag &= FLAG_ON_CURVE + FLAG_OVERLAP_SIMPLE; - encode_coord (deltas[i].first, flag, FLAG_X_SHORT, FLAG_X_SAME, x_coords); - encode_coord (deltas[i].second, flag, FLAG_Y_SHORT, FLAG_Y_SAME, y_coords); + float cur_x = roundf (all_points[i].x); + float cur_y = roundf (all_points[i].y); + encode_coord (cur_x - prev_x, flag, FLAG_X_SHORT, FLAG_X_SAME, x_coords); + encode_coord (cur_y - prev_y, flag, FLAG_Y_SHORT, FLAG_Y_SAME, y_coords); if (i == 0) lastflag = flag + 1; //make lastflag != flag for the first point encode_flag (flag, repeat, lastflag, flags); + + prev_x = cur_x; + prev_y = cur_y; } unsigned len_before_instrs = 2 * header.numberOfContours + 2; diff --git a/thirdparty/harfbuzz/src/OT/glyf/SubsetGlyph.hh b/thirdparty/harfbuzz/src/OT/glyf/SubsetGlyph.hh index 7ddefc5a91..88fc93c435 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/SubsetGlyph.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/SubsetGlyph.hh @@ -14,7 +14,6 @@ namespace glyf_impl { struct SubsetGlyph { - hb_codepoint_t new_gid; hb_codepoint_t old_gid; Glyph source_glyph; hb_bytes_t dest_start; /* region of source_glyph to copy first */ diff --git a/thirdparty/harfbuzz/src/OT/glyf/glyf.hh b/thirdparty/harfbuzz/src/OT/glyf/glyf.hh index be2cb1d0dc..5fb32f67f3 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/glyf.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/glyf.hh @@ -72,10 +72,13 @@ struct glyf if (unlikely (!c->serializer->check_success (glyf_prime))) return_trace (false); hb_vector_t<glyf_impl::SubsetGlyph> glyphs; - _populate_subset_glyphs (c->plan, &glyphs); + _populate_subset_glyphs (c->plan, glyphs); if (!c->plan->pinned_at_default) - _compile_subset_glyphs_with_deltas (c->plan, &glyphs); + { + if (!_compile_subset_glyphs_with_deltas (c->plan, &glyphs)) + return_trace (false); + } auto padded_offsets = + hb_iter (glyphs) @@ -105,9 +108,9 @@ struct glyf void _populate_subset_glyphs (const hb_subset_plan_t *plan, - hb_vector_t<glyf_impl::SubsetGlyph> *glyphs /* OUT */) const; - - void + hb_vector_t<glyf_impl::SubsetGlyph> &glyphs /* OUT */) const; + + bool _compile_subset_glyphs_with_deltas (const hb_subset_plan_t *plan, hb_vector_t<glyf_impl::SubsetGlyph> *glyphs /* OUT */) const; @@ -180,7 +183,7 @@ struct glyf_accelerator_t contour_point_vector_t all_points; bool phantom_only = !consumer.is_consuming_contour_points (); - if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, nullptr, true, phantom_only))) + if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, nullptr, true, true, phantom_only))) return false; if (consumer.is_consuming_contour_points ()) @@ -374,44 +377,43 @@ struct glyf_accelerator_t inline void glyf::_populate_subset_glyphs (const hb_subset_plan_t *plan, - hb_vector_t<glyf_impl::SubsetGlyph> *glyphs /* OUT */) const + hb_vector_t<glyf_impl::SubsetGlyph>& glyphs /* OUT */) const { OT::glyf_accelerator_t glyf (plan->source); + unsigned num_glyphs = plan->num_output_glyphs (); + if (!glyphs.resize (num_glyphs)) return; - + hb_range (plan->num_output_glyphs ()) - | hb_map ([&] (hb_codepoint_t new_gid) - { - glyf_impl::SubsetGlyph subset_glyph = {0}; - subset_glyph.new_gid = new_gid; - - /* should never fail: all old gids should be mapped */ - if (!plan->old_gid_for_new_gid (new_gid, &subset_glyph.old_gid)) - return subset_glyph; - - if (new_gid == 0 && - !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) - subset_glyph.source_glyph = glyf_impl::Glyph (); - else - subset_glyph.source_glyph = glyf.glyph_for_gid (subset_glyph.old_gid, true); - if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING) - subset_glyph.drop_hints_bytes (); - else - subset_glyph.dest_start = subset_glyph.source_glyph.get_bytes (); - return subset_glyph; - }) - | hb_sink (glyphs) - ; + for (auto p : plan->glyph_map->iter ()) + { + unsigned new_gid = p.second; + glyf_impl::SubsetGlyph& subset_glyph = glyphs.arrayZ[new_gid]; + subset_glyph.old_gid = p.first; + + if (unlikely (new_gid == 0 && + !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) && + plan->pinned_at_default) + subset_glyph.source_glyph = glyf_impl::Glyph (); + else + subset_glyph.source_glyph = glyf.glyph_for_gid (subset_glyph.old_gid, true); + + if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING) + subset_glyph.drop_hints_bytes (); + else + subset_glyph.dest_start = subset_glyph.source_glyph.get_bytes (); + } } -inline void +inline bool glyf::_compile_subset_glyphs_with_deltas (const hb_subset_plan_t *plan, hb_vector_t<glyf_impl::SubsetGlyph> *glyphs /* OUT */) const { OT::glyf_accelerator_t glyf (plan->source); hb_font_t *font = hb_font_create (plan->source); + if (unlikely (!font)) return false; hb_vector_t<hb_variation_t> vars; - vars.alloc (plan->user_axes_location->get_population ()); + if (unlikely (!vars.alloc (plan->user_axes_location->get_population ()))) + return false; for (auto _ : *plan->user_axes_location) { @@ -423,9 +425,16 @@ glyf::_compile_subset_glyphs_with_deltas (const hb_subset_plan_t *plan, hb_font_set_variations (font, vars.arrayZ, plan->user_axes_location->get_population ()); for (auto& subset_glyph : *glyphs) - const_cast<glyf_impl::SubsetGlyph &> (subset_glyph).compile_bytes_with_deltas (plan, font, glyf); + { + if (!const_cast<glyf_impl::SubsetGlyph &> (subset_glyph).compile_bytes_with_deltas (plan, font, glyf)) + { + hb_font_destroy (font); + return false; + } + } hb_font_destroy (font); + return true; } |