[instancer] compile composite glyphs directly with shifted component

points instead of deltas
This commit is contained in:
Qunxin Liu 2023-04-21 14:12:27 -07:00 committed by Behdad Esfahbod
parent 3520f528aa
commit 591c9460dc
2 changed files with 21 additions and 31 deletions

View File

@ -113,8 +113,8 @@ struct CompositeGlyphRecord
return true; return true;
} }
unsigned compile_with_deltas (const contour_point_t &p_delta, unsigned compile_with_point (const contour_point_t &point,
char *out) const char *out) const
{ {
const HBINT8 *p = &StructAfter<const HBINT8> (flags); const HBINT8 *p = &StructAfter<const HBINT8> (flags);
#ifndef HB_NO_BEYOND_64K #ifndef HB_NO_BEYOND_64K
@ -128,18 +128,17 @@ struct CompositeGlyphRecord
unsigned len_before_val = (const char *)p - (const char *)this; unsigned len_before_val = (const char *)p - (const char *)this;
if (flags & ARG_1_AND_2_ARE_WORDS) if (flags & ARG_1_AND_2_ARE_WORDS)
{ {
// no overflow, copy and update value with deltas // no overflow, copy value
hb_memcpy (out, this, len); hb_memcpy (out, this, len);
const HBINT16 *px = reinterpret_cast<const HBINT16 *> (p);
HBINT16 *o = reinterpret_cast<HBINT16 *> (out + len_before_val); HBINT16 *o = reinterpret_cast<HBINT16 *> (out + len_before_val);
o[0] = px[0] + roundf (p_delta.x); o[0] = roundf (point.x);
o[1] = px[1] + roundf (p_delta.y); o[1] = roundf (point.y);
} }
else else
{ {
int new_x = p[0] + roundf (p_delta.x); int new_x = roundf (point.x);
int new_y = p[1] + roundf (p_delta.y); int new_y = roundf (point.y);
if (new_x <= 127 && new_x >= -128 && if (new_x <= 127 && new_x >= -128 &&
new_y <= 127 && new_y >= -128) new_y <= 127 && new_y >= -128)
{ {
@ -150,7 +149,7 @@ struct CompositeGlyphRecord
} }
else else
{ {
// int8 overflows after deltas applied // new point value has an int8 overflow
hb_memcpy (out, this, len_before_val); hb_memcpy (out, this, len_before_val);
//update flags //update flags
@ -332,7 +331,7 @@ struct CompositeGlyph
} }
bool compile_bytes_with_deltas (const hb_bytes_t &source_bytes, bool compile_bytes_with_deltas (const hb_bytes_t &source_bytes,
const contour_point_vector_t &deltas, const contour_point_vector_t &points_with_deltas,
hb_bytes_t &dest_bytes /* OUT */) hb_bytes_t &dest_bytes /* OUT */)
{ {
if (source_bytes.length <= GlyphHeader::static_size || if (source_bytes.length <= GlyphHeader::static_size ||
@ -357,8 +356,8 @@ struct CompositeGlyph
unsigned i = 0, source_comp_len = 0; unsigned i = 0, source_comp_len = 0;
for (const auto &component : it) for (const auto &component : it)
{ {
/* last 4 points in deltas are phantom points and should not be included */ /* last 4 points in points_with_deltas are phantom points and should not be included */
if (i >= deltas.length - 4) { if (i >= points_with_deltas.length - 4) {
free (o); free (o);
return false; return false;
} }
@ -371,7 +370,7 @@ struct CompositeGlyph
} }
else else
{ {
unsigned new_len = component.compile_with_deltas (deltas[i], p); unsigned new_len = component.compile_with_point (points_with_deltas[i], p);
p += new_len; p += new_len;
} }
i++; i++;

View File

@ -205,7 +205,7 @@ struct Glyph
hb_bytes_t &dest_start, /* IN/OUT */ hb_bytes_t &dest_start, /* IN/OUT */
hb_bytes_t &dest_end /* OUT */) hb_bytes_t &dest_end /* OUT */)
{ {
contour_point_vector_t all_points, deltas; contour_point_vector_t all_points, points_with_deltas;
unsigned composite_contours = 0; unsigned composite_contours = 0;
head_maxp_info_t *head_maxp_info_p = &plan->head_maxp_info; head_maxp_info_t *head_maxp_info_p = &plan->head_maxp_info;
unsigned *composite_contours_p = &composite_contours; unsigned *composite_contours_p = &composite_contours;
@ -219,7 +219,7 @@ struct Glyph
composite_contours_p = nullptr; composite_contours_p = nullptr;
} }
if (!get_points (font, glyf, all_points, &deltas, head_maxp_info_p, composite_contours_p, false, false)) if (!get_points (font, glyf, all_points, &points_with_deltas, head_maxp_info_p, composite_contours_p, false, false))
return false; return false;
// .notdef, set type to empty so we only update metrics and don't compile bytes for // .notdef, set type to empty so we only update metrics and don't compile bytes for
@ -246,7 +246,7 @@ struct Glyph
case COMPOSITE: case COMPOSITE:
if (!CompositeGlyph (*header, bytes).compile_bytes_with_deltas (dest_start, if (!CompositeGlyph (*header, bytes).compile_bytes_with_deltas (dest_start,
deltas, points_with_deltas,
dest_end)) dest_end))
return false; return false;
break; break;
@ -280,7 +280,7 @@ struct Glyph
template <typename accelerator_t> template <typename accelerator_t>
bool get_points (hb_font_t *font, const accelerator_t &glyf_accelerator, bool get_points (hb_font_t *font, const accelerator_t &glyf_accelerator,
contour_point_vector_t &all_points /* OUT */, contour_point_vector_t &all_points /* OUT */,
contour_point_vector_t *deltas = nullptr, /* OUT */ contour_point_vector_t *points_with_deltas = nullptr, /* OUT */
head_maxp_info_t * head_maxp_info = nullptr, /* OUT */ head_maxp_info_t * head_maxp_info = nullptr, /* OUT */
unsigned *composite_contours = nullptr, /* OUT */ unsigned *composite_contours = nullptr, /* OUT */
bool shift_points_hori = true, bool shift_points_hori = true,
@ -364,12 +364,6 @@ struct Glyph
phantoms[PHANTOM_BOTTOM].y = v_orig - (int) v_adv; phantoms[PHANTOM_BOTTOM].y = v_orig - (int) v_adv;
} }
if (deltas != nullptr && depth == 0 && type == COMPOSITE)
{
if (unlikely (!deltas->resize (points.length))) return false;
deltas->copy_vector (points);
}
#ifndef HB_NO_VAR #ifndef HB_NO_VAR
glyf_accelerator.gvar->apply_deltas_to_points (gid, glyf_accelerator.gvar->apply_deltas_to_points (gid,
coords, coords,
@ -378,13 +372,10 @@ struct Glyph
// mainly used by CompositeGlyph calculating new X/Y offset value so no need to extend it // mainly used by CompositeGlyph calculating new X/Y offset value so no need to extend it
// with child glyphs' points // with child glyphs' points
if (deltas != nullptr && depth == 0 && type == COMPOSITE) if (points_with_deltas != nullptr && depth == 0 && type == COMPOSITE)
{ {
for (unsigned i = 0 ; i < points.length; i++) if (unlikely (!points_with_deltas->resize (points.length))) return false;
{ points_with_deltas->copy_vector (points);
deltas->arrayZ[i].x = points.arrayZ[i].x - deltas->arrayZ[i].x;
deltas->arrayZ[i].y = points.arrayZ[i].y - deltas->arrayZ[i].y;
}
} }
switch (type) { switch (type) {
@ -405,7 +396,7 @@ struct Glyph
.get_points (font, .get_points (font,
glyf_accelerator, glyf_accelerator,
comp_points, comp_points,
deltas, points_with_deltas,
head_maxp_info, head_maxp_info,
composite_contours, composite_contours,
shift_points_hori, shift_points_hori,
@ -481,7 +472,7 @@ struct Glyph
.get_points (font, .get_points (font,
glyf_accelerator, glyf_accelerator,
comp_points, comp_points,
deltas, points_with_deltas,
head_maxp_info, head_maxp_info,
nullptr, nullptr,
shift_points_hori, shift_points_hori,