Merge remote-tracking branch 'upstream/master' into var-subset

pull/1594/head
Ebrahim Byagowi 5 years ago
commit 453050ad30
  1. 3
      src/gen-use-table.py
  2. 10
      src/hb-algs.hh
  3. 3
      src/hb-buffer.cc
  4. 11
      src/hb-cff-interp-common.hh
  5. 15
      src/hb-common.h
  6. 12
      src/hb-ot-cff1-table.cc
  7. 2
      src/hb-ot-cff1-table.hh
  8. 8
      src/hb-ot-cff2-table.cc
  9. 14
      src/hb-ot-color-cbdt-table.hh
  10. 15
      src/hb-ot-color-sbix-table.hh
  11. 16
      src/hb-ot-font.cc
  12. 985
      src/hb-ot-glyf-table.hh
  13. 16
      src/hb-ot-hmtx-table.hh
  14. 54
      src/hb-ot-layout-common.hh
  15. 59
      src/hb-ot-layout-gsub-table.hh
  16. 2
      src/hb-ot-map.cc
  17. 2
      src/hb-ot-shape-complex-use-table.cc
  18. 19
      src/hb-ot-var-gvar-table.hh
  19. 5
      src/hb-ot-var-hvar-table.hh
  20. 4
      src/hb-shape.cc
  21. 3
      src/hb-subset-cff-common.cc
  22. 2
      src/hb-subset-cff-common.hh
  23. 2
      src/hb-subset-cff1.cc
  24. 2
      src/hb-subset-cff2.cc
  25. 25
      src/hb-subset-plan.cc
  26. 18
      test/api/test-ot-extents-cff.c

@ -383,6 +383,9 @@ def map_to_use(data):
# TODO: In USE's override list but not in Unicode 12.0
if U == 0x103C: UIPC = Left
# TODO: https://github.com/harfbuzz/harfbuzz/pull/2012
if U == 0x1C29: UIPC = Left
# TODO: These are not in USE's override list that we have, nor are they in Unicode 12.0
if 0xA926 <= U <= 0xA92A: UIPC = Top
# TODO: https://github.com/harfbuzz/harfbuzz/pull/1037

@ -588,10 +588,18 @@ hb_memcmp (const void *a, const void *b, unsigned int len)
/* It's illegal to pass NULL to memcmp(), even if len is zero.
* So, wrap it.
* https://sourceware.org/bugzilla/show_bug.cgi?id=23878 */
if (!len) return 0;
if (unlikely (!len)) return 0;
return memcmp (a, b, len);
}
static inline void *
hb_memset (void *s, int c, unsigned int n)
{
/* It's illegal to pass NULL to memset(), even if n is zero. */
if (unlikely (!n)) return 0;
return memset (s, c, n);
}
static inline bool
hb_unsigned_mul_overflows (unsigned int count, unsigned int size)
{

@ -324,8 +324,7 @@ hb_buffer_t::clear_positions ()
out_len = 0;
out_info = info;
if (likely (len))
memset (pos, 0, sizeof (pos[0]) * len);
hb_memset (pos, 0, sizeof (pos[0]) * len);
}
void

@ -220,18 +220,15 @@ struct number_t
void init () { set_real (0.0); }
void fini () {}
void set_int (int v) { value = (double) v; }
int to_int () const { return (int) value; }
void set_int (int v) { value = v; }
int to_int () const { return value; }
void set_fixed (int32_t v) { value = v / 65536.0; }
int32_t to_fixed () const { return (int32_t) (value * 65536.0); }
int32_t to_fixed () const { return value * 65536.0; }
void set_real (double v) { value = v; }
double to_real () const { return value; }
int ceil () const { return (int) ::ceil (value); }
int floor () const { return (int) ::floor (value); }
bool in_int_range () const
{ return ((double) (int16_t) to_int () == value); }
@ -248,7 +245,7 @@ struct number_t
}
protected:
double value;
double value;
};
/* byte string */

@ -425,6 +425,21 @@ typedef void (*hb_destroy_func_t) (void *user_data);
*/
#define HB_FEATURE_GLOBAL_END ((unsigned int) -1)
/**
* hb_feature_t:
* @tag: a feature tag
* @value: 0 disables the feature, non-zero (usually 1) enables the feature.
* For features implemented as lookup type 3 (like 'salt') the @value is a one
* based index into the alternates.
* @start: the cluster to start applying this feature setting (inclusive).
* @end: the cluster to end applying this feature setting (exclusive).
*
* The hb_feature_t is the structure that holds information about requested
* feature application. The feature will be applied with the given value to all
* glyphs which are in clusters between @start (inclusive) and @end (exclusive).
* Setting start to @HB_FEATURE_GLOBAL_START and end to @HB_FEATURE_GLOBAL_END
* specifies that the feature always applies to the entire buffer.
*/
typedef struct hb_feature_t {
hb_tag_t tag;
uint32_t value;

@ -306,14 +306,14 @@ bool _get_bounds (const OT::cff1::accelerator_t *cff, hb_codepoint_t glyph, boun
return true;
}
bool OT::cff1::accelerator_t::get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
bool OT::cff1::accelerator_t::get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
{
#ifdef HB_NO_OT_FONT_CFF
/* XXX Remove check when this code moves to .hh file. */
return true;
#endif
bounds_t bounds;
bounds_t bounds;
if (!_get_bounds (this, glyph, bounds))
return false;
@ -325,8 +325,8 @@ bool OT::cff1::accelerator_t::get_extents (hb_codepoint_t glyph, hb_glyph_extent
}
else
{
extents->x_bearing = (int32_t)bounds.min.x.floor ();
extents->width = (int32_t)bounds.max.x.ceil () - extents->x_bearing;
extents->x_bearing = font->em_scalef_x (bounds.min.x.to_real ());
extents->width = font->em_scalef_x (bounds.max.x.to_real () - bounds.min.x.to_real ());
}
if (bounds.min.y >= bounds.max.y)
{
@ -335,8 +335,8 @@ bool OT::cff1::accelerator_t::get_extents (hb_codepoint_t glyph, hb_glyph_extent
}
else
{
extents->y_bearing = (int32_t)bounds.max.y.ceil ();
extents->height = (int32_t)bounds.min.y.floor () - extents->y_bearing;
extents->y_bearing = font->em_scalef_y (bounds.max.y.to_real ());
extents->height = font->em_scalef_x (bounds.min.y.to_real () - bounds.max.y.to_real ());
}
return true;

@ -1196,7 +1196,7 @@ struct cff1
struct accelerator_t : accelerator_templ_t<cff1_private_dict_opset_t, cff1_private_dict_values_t>
{
HB_INTERNAL bool get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const;
HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const;
HB_INTERNAL bool get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const;
};

@ -125,8 +125,8 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font,
}
else
{
extents->x_bearing = (int32_t)param.min_x.floor ();
extents->width = (int32_t)param.max_x.ceil () - extents->x_bearing;
extents->x_bearing = font->em_scalef_x (param.min_x.to_real ());
extents->width = font->em_scalef_x (param.max_x.to_real () - param.min_x.to_real ());
}
if (param.min_y >= param.max_y)
{
@ -135,8 +135,8 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font,
}
else
{
extents->y_bearing = (int32_t)param.max_y.ceil ();
extents->height = (int32_t)param.min_y.floor () - extents->y_bearing;
extents->y_bearing = font->em_scalef_y (param.max_y.to_real ());
extents->height = font->em_scalef_y (param.min_y.to_real () - param.max_y.to_real ());
}
return true;

@ -51,12 +51,12 @@ struct SmallGlyphMetrics
return_trace (c->check_struct (this));
}
void get_extents (hb_glyph_extents_t *extents) const
void get_extents (hb_font_t *font, hb_glyph_extents_t *extents) const
{
extents->x_bearing = bearingX;
extents->y_bearing = bearingY;
extents->width = width;
extents->height = - (hb_position_t) height;
extents->x_bearing = font->em_scale_x (bearingX);
extents->y_bearing = font->em_scale_y (bearingY);
extents->width = font->em_scale_x (width);
extents->height = font->em_scale_y (-height);
}
HBUINT8 height;
@ -424,7 +424,7 @@ struct CBDT
return false;
const GlyphBitmapDataFormat17& glyphFormat17 =
StructAtOffset<GlyphBitmapDataFormat17> (this->cbdt, image_offset);
glyphFormat17.glyphMetrics.get_extents (extents);
glyphFormat17.glyphMetrics.get_extents (font, extents);
break;
}
case 18: {
@ -432,7 +432,7 @@ struct CBDT
return false;
const GlyphBitmapDataFormat18& glyphFormat18 =
StructAtOffset<GlyphBitmapDataFormat18> (this->cbdt, image_offset);
glyphFormat18.glyphMetrics.get_extents (extents);
glyphFormat18.glyphMetrics.get_extents (font, extents);
break;
}
default:

@ -243,10 +243,17 @@ struct sbix
if (strike_ppem)
{
float scale = font->face->get_upem () / (float) strike_ppem;
extents->x_bearing = roundf (extents->x_bearing * scale);
extents->y_bearing = roundf (extents->y_bearing * scale);
extents->width = roundf (extents->width * scale);
extents->height = roundf (extents->height * scale);
extents->x_bearing = font->em_scalef_x (extents->x_bearing * scale);
extents->y_bearing = font->em_scalef_y (extents->y_bearing * scale);
extents->width = font->em_scalef_x (extents->width * scale);
extents->height = font->em_scalef_y (extents->height * scale);
}
else
{
extents->x_bearing = font->em_scale_x (extents->x_bearing);
extents->y_bearing = font->em_scale_y (extents->y_bearing);
extents->width = font->em_scale_x (extents->width);
extents->height = font->em_scale_y (extents->height);
}
hb_blob_destroy (blob);

@ -164,7 +164,7 @@ hb_ot_get_glyph_v_origin (hb_font_t *font,
{
const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx;
hb_position_t tsb = vmtx.get_side_bearing (font, glyph);
*y = font->em_scale_y (extents.y_bearing + tsb);
*y = extents.y_bearing + font->em_scale_y (tsb);
return true;
}
@ -190,7 +190,7 @@ hb_ot_get_glyph_extents (hb_font_t *font,
#endif
if (!ret) ret = ot_face->glyf->get_extents (font, glyph, extents);
#ifndef HB_NO_OT_FONT_CFF
if (!ret) ret = ot_face->cff1->get_extents (glyph, extents);
if (!ret) ret = ot_face->cff1->get_extents (font, glyph, extents);
if (!ret) ret = ot_face->cff2->get_extents (font, glyph, extents);
#endif
#if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR)
@ -198,10 +198,6 @@ hb_ot_get_glyph_extents (hb_font_t *font,
#endif
// TODO Hook up side-bearings variations.
extents->x_bearing = font->em_scale_x (extents->x_bearing);
extents->y_bearing = font->em_scale_y (extents->y_bearing);
extents->width = font->em_scale_x (extents->width);
extents->height = font->em_scale_y (extents->height);
return ret;
}
@ -317,15 +313,15 @@ hb_ot_font_set_funcs (hb_font_t *font)
#ifndef HB_NO_VAR
int
hb_ot_get_side_bearing_var_tt (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical)
_glyf_get_side_bearing_var (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical)
{
return font->face->table.glyf->get_side_bearing_var (glyph, font->coords, font->num_coords, is_vertical);
return font->face->table.glyf->get_side_bearing_var (font, glyph, is_vertical);
}
unsigned
hb_ot_get_advance_var_tt (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical)
_glyf_get_advance_var (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical)
{
return font->face->table.glyf->get_advance_var (glyph, font->coords, font->num_coords, is_vertical);
return font->face->table.glyf->get_advance_var (font, glyph, is_vertical);
}
#endif

File diff suppressed because it is too large Load Diff

@ -43,10 +43,10 @@
HB_INTERNAL int
hb_ot_get_side_bearing_var_tt (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical);
_glyf_get_side_bearing_var (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical);
HB_INTERNAL unsigned
hb_ot_get_advance_var_tt (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical);
_glyf_get_advance_var (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical);
namespace OT {
@ -215,10 +215,10 @@ struct hmtxvmtx
if (unlikely (glyph >= num_metrics) || !font->num_coords)
return side_bearing;
if (var_table.get_blob () == &Null (hb_blob_t))
return hb_ot_get_side_bearing_var_tt (font, glyph, T::tableTag == HB_OT_TAG_vmtx);
if (var_table.get_length ())
return side_bearing + var_table->get_side_bearing_var (glyph, font->coords, font->num_coords); // TODO Optimize?!
return side_bearing + var_table->get_side_bearing_var (glyph, font->coords, font->num_coords); // TODO Optimize?!
return _glyf_get_side_bearing_var (font, glyph, T::tableTag == HB_OT_TAG_vmtx);
#else
return side_bearing;
#endif
@ -249,10 +249,10 @@ struct hmtxvmtx
if (unlikely (glyph >= num_metrics) || !font->num_coords)
return advance;
if (var_table.get_blob () == &Null (hb_blob_t))
return hb_ot_get_advance_var_tt (font, glyph, T::tableTag == HB_OT_TAG_vmtx);
if (var_table.get_length ())
return advance + roundf (var_table->get_advance_var (glyph, font)); // TODO Optimize?!
return advance + roundf (var_table->get_advance_var (glyph, font->coords, font->num_coords)); // TODO Optimize?!
return _glyf_get_advance_var (font, glyph, T::tableTag == HB_OT_TAG_vmtx);
#else
return advance;
#endif

@ -66,6 +66,60 @@ namespace OT {
#define NOT_COVERED ((unsigned int) -1)
template<typename OutputArray>
struct subset_offset_array_t
{
subset_offset_array_t
(hb_subset_context_t *subset_context,
OutputArray& out,
const void *src_base,
const void *dest_base)
: _subset_context(subset_context), _out (out), _src_base (src_base), _dest_base (dest_base) {}
template <typename T>
bool
operator ()
(T&& offset)
{
auto *o = _out.serialize_append (_subset_context->serializer);
if (unlikely (!o)) return false;
auto snap = _subset_context->serializer->snapshot ();
bool ret = o->serialize_subset (_subset_context, offset, _src_base, _dest_base);
if (!ret)
{
_out.pop ();
_subset_context->serializer->revert (snap);
}
return ret;
}
private:
hb_subset_context_t *_subset_context;
OutputArray &_out;
const void *_src_base;
const void *_dest_base;
};
/*
* Helper to subset an array of offsets. Subsets the thing pointed to by each offset
* and discards the offset in the array if the subset operation results in an empty
* thing.
*/
struct
{
template<typename OutputArray>
subset_offset_array_t<OutputArray>
operator ()
(hb_subset_context_t *subset_context,
OutputArray& out,
const void *src_base,
const void *dest_base) const
{
return subset_offset_array_t<OutputArray> (subset_context, out, src_base, dest_base);
}
}
HB_FUNCOBJ (subset_offset_array);
/*
*

@ -452,20 +452,7 @@ struct MultipleSubstFormat1
hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+ hb_zip (this+coverage, sequence)
| hb_filter (glyphset, hb_first)
| hb_filter ([this, c, out] (const OffsetTo<Sequence>& _)
{
auto *o = out->sequence.serialize_append (c->serializer);
if (unlikely (!o)) return false;
auto snap = c->serializer->snapshot ();
bool ret = o->serialize_subset (c, _, this, out);
if (!ret)
{
out->sequence.pop ();
c->serializer->revert (snap);
}
return ret;
},
hb_second)
| hb_filter (subset_offset_array (c, out->sequence, this, out), hb_second)
| hb_map (hb_first)
| hb_map (glyph_map)
| hb_sink (new_coverage)
@ -675,20 +662,7 @@ struct AlternateSubstFormat1
hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+ hb_zip (this+coverage, alternateSet)
| hb_filter (glyphset, hb_first)
| hb_filter ([this, c, out] (const OffsetTo<AlternateSet>& _)
{
auto *o = out->alternateSet.serialize_append (c->serializer);
if (unlikely (!o)) return false;
auto snap = c->serializer->snapshot ();
bool ret = o->serialize_subset (c, _, this, out);
if (!ret)
{
out->alternateSet.pop ();
c->serializer->revert (snap);
}
return ret;
},
hb_second)
| hb_filter (subset_offset_array (c, out->alternateSet, this, out), hb_second)
| hb_map (hb_first)
| hb_map (glyph_map)
| hb_sink (new_coverage)
@ -948,19 +922,7 @@ struct LigatureSet
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+ hb_iter (ligature)
| hb_filter ([this, c, out] (const OffsetTo<Ligature>& _)
{
auto *o = out->ligature.serialize_append (c->serializer);
if (unlikely (!o)) return false;
auto snap = c->serializer->snapshot ();
bool ret = o->serialize_subset (c, _, this, out);
if (!ret)
{
out->ligature.pop ();
c->serializer->revert (snap);
}
return ret;
})
| hb_filter (subset_offset_array (c, out->ligature, this, out))
| hb_drain
;
return_trace (bool (out->ligature));
@ -1074,20 +1036,7 @@ struct LigatureSubstFormat1
hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+ hb_zip (this+coverage, ligatureSet)
| hb_filter (glyphset, hb_first)
| hb_filter ([this, c, out] (const OffsetTo<LigatureSet>& _)
{
auto *o = out->ligatureSet.serialize_append (c->serializer);
if (unlikely (!o)) return false;
auto snap = c->serializer->snapshot ();
bool ret = o->serialize_subset (c, _, this, out);
if (!ret)
{
out->ligatureSet.pop ();
c->serializer->revert (snap);
}
return ret;
},
hb_second)
| hb_filter (subset_offset_array (c, out->ligatureSet, this, out), hb_second)
| hb_map (hb_first)
| hb_map (glyph_map)
| hb_sink (new_coverage)

@ -38,7 +38,7 @@
void hb_ot_map_t::collect_lookups (unsigned int table_index, hb_set_t *lookups_out) const
{
for (unsigned int i = 0; i < lookups[table_index].length; i++)
hb_set_add (lookups_out, lookups[table_index][i].index);
lookups_out->add (lookups[table_index][i].index);
}

@ -347,7 +347,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 1C00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1C10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1C20 */ B, B, B, B, SUB, SUB, VPst, VPre, VPre, VPst, VPst, VPst, VBlw, FAbv, FAbv, FAbv,
/* 1C20 */ B, B, B, B, SUB, SUB, VPst, VPre, VPre, VPre, VPst, VPst, VBlw, FAbv, FAbv, FAbv,
/* 1C30 */ FAbv, FAbv, FAbv, FAbv, VMPre, VMPre, FMAbv, CMBlw, O, O, O, O, O, O, O, O,
/* 1C40 */ B, B, B, B, B, B, B, B, B, B, O, O, O, B, B, B,

@ -80,20 +80,19 @@ struct contour_point_vector_t : hb_vector_t<contour_point_t>
struct range_checker_t
{
range_checker_t (const void *table_, unsigned int start_offset_, unsigned int end_offset_)
: table ((const char*) table_), start_offset (start_offset_), end_offset (end_offset_) {}
range_checker_t (const void *data_, unsigned int length_)
: data ((const char *) data_), length (length_) {}
template <typename T>
bool in_range (const T *p) const
bool in_range (const T *p, unsigned int size = T::static_size) const
{
return ((const char *) p) >= table + start_offset
&& ((const char *) p + T::static_size) <= table + end_offset;
return ((const char *) p) >= data
&& ((const char *) p + size) <= data + length;
}
protected:
const char *table;
const unsigned int start_offset;
const unsigned int end_offset;
const char *data;
const unsigned int length;
};
struct Tuple : UnsizedArrayOf<F2DOT14> {};
@ -234,7 +233,7 @@ struct GlyphVarData
{
if (var_data->has_shared_point_numbers ())
{
range_checker_t checker (var_data, 0, length);
range_checker_t checker (var_data, length);
const HBUINT8 *base = &(var_data+var_data->data);
const HBUINT8 *p = base;
if (!unpack_points (p, shared_indices, checker)) return false;
@ -612,7 +611,7 @@ struct gvar
if (unlikely (!iterator.in_range (p, length)))
return false;
range_checker_t checker (p, 0, length);
range_checker_t checker (p, length);
hb_vector_t<unsigned int> private_indices;
if (iterator.current_tuple->has_private_points () &&
!GlyphVarData::unpack_points (p, private_indices, checker))

@ -403,11 +403,10 @@ struct HVARVVAR
hvar_plan.index_map_plans.as_array ()));
}
float get_advance_var (hb_codepoint_t glyph,
const int *coords, unsigned int coord_count) const
float get_advance_var (hb_codepoint_t glyph, hb_font_t *font) const
{
unsigned int varidx = (this+advMap).map (glyph);
return (this+varStore).get_delta (varidx, coords, coord_count);
return (this+varStore).get_delta (varidx, font->coords, font->num_coords);
}
float get_side_bearing_var (hb_codepoint_t glyph,

@ -154,7 +154,9 @@ hb_shape_full (hb_font_t *font,
*
* Shapes @buffer using @font turning its Unicode characters content to
* positioned glyphs. If @features is not %NULL, it will be used to control the
* features applied during shaping.
* features applied during shaping. If two @features have the same tag but
* overlapping ranges the value of the feature with the higher index takes
* precedence.
*
* Since: 0.9.2
**/

@ -68,8 +68,7 @@ hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan,
{
/* use hb_set to determine the subset of font dicts */
hb_set_t *set = hb_set_create ();
if (set == &Null (hb_set_t))
return false;
if (unlikely (set == &Null (hb_set_t))) return false;
hb_codepoint_t prev_fd = CFF_UNDEF_CODE;
for (hb_codepoint_t i = 0; i < subset_num_glyphs; i++)
{

@ -916,7 +916,7 @@ struct subr_subsetter_t
hb_set_t *closure,
const subr_subset_param_t &param)
{
hb_set_add (closure, subr_num);
closure->add (subr_num);
collect_subr_refs_in_str (subrs[subr_num], param);
}

@ -389,7 +389,7 @@ struct cff1_cs_opset_subr_subset_t : cff1_cs_opset_t<cff1_cs_opset_subr_subset_t
byte_str_ref_t str_ref = env.str_ref;
env.call_subr (subrs, type);
param.current_parsed_str->add_call_op (op, str_ref, env.context.subr_num);
hb_set_add (closure, env.context.subr_num);
closure->add (env.context.subr_num);
param.set_current_str (env, true);
}

@ -219,7 +219,7 @@ struct cff2_cs_opset_subr_subset_t : cff2_cs_opset_t<cff2_cs_opset_subr_subset_t
byte_str_ref_t str_ref = env.str_ref;
env.call_subr (subrs, type);
param.current_parsed_str->add_call_op (op, str_ref, env.context.subr_num);
hb_set_add (closure, env.context.subr_num);
closure->add (env.context.subr_num);
param.set_current_str (env, true);
}

@ -34,32 +34,17 @@
#include "hb-ot-var-fvar-table.hh"
#include "hb-ot-stat-table.hh"
static inline void
_add_gid_and_children (const OT::glyf::accelerator_t &glyf,
hb_codepoint_t gid,
hb_set_t *gids_to_retain)
{
if (gids_to_retain->has (gid))
// Already visited this gid, ignore.
return;
hb_set_add (gids_to_retain, gid);
for (auto &item : OT::glyf::get_composite_iterator (glyf.bytes_for_glyph (gid)))
_add_gid_and_children (glyf, item.glyphIndex, gids_to_retain);
}
#ifndef HB_NO_SUBSET_CFF
static inline void
_add_cff_seac_components (const OT::cff1::accelerator_t &cff,
hb_codepoint_t gid,
hb_set_t *gids_to_retain)
hb_codepoint_t gid,
hb_set_t *gids_to_retain)
{
hb_codepoint_t base_gid, accent_gid;
if (cff.get_seac_components (gid, &base_gid, &accent_gid))
{
hb_set_add (gids_to_retain, base_gid);
hb_set_add (gids_to_retain, accent_gid);
gids_to_retain->add (base_gid);
gids_to_retain->add (accent_gid);
}
}
#endif
@ -145,7 +130,7 @@ _populate_gids_to_retain (hb_subset_plan_t* plan,
hb_codepoint_t gid = HB_SET_VALUE_INVALID;
while (plan->_glyphset_gsub->next (&gid))
{
_add_gid_and_children (glyf, gid, plan->_glyphset);
glyf.add_gid_and_children (gid, plan->_glyphset);
#ifndef HB_NO_SUBSET_CFF
if (cff.is_valid ())
_add_cff_seac_components (cff, gid, plan->_glyphset);

@ -146,8 +146,8 @@ test_extents_cff2 (void)
g_assert_cmpint (extents.x_bearing, ==, 38);
g_assert_cmpint (extents.y_bearing, ==, 493);
g_assert_cmpint (extents.width, ==, 481);
g_assert_cmpint (extents.height, ==, -508);
g_assert_cmpint (extents.width, ==, 480);
g_assert_cmpint (extents.height, ==, -507);
hb_font_destroy (font);
}
@ -168,17 +168,17 @@ test_extents_cff2_vsindex (void)
hb_bool_t result = hb_font_get_glyph_extents (font, 1, &extents);
g_assert (result);
g_assert_cmpint (extents.x_bearing, ==, 11);
g_assert_cmpint (extents.y_bearing, ==, 656);
g_assert_cmpint (extents.width, ==, 653);
g_assert_cmpint (extents.height, ==, -656);
g_assert_cmpint (extents.x_bearing, ==, 12);
g_assert_cmpint (extents.y_bearing, ==, 655);
g_assert_cmpint (extents.width, ==, 652);
g_assert_cmpint (extents.height, ==, -655);
result = hb_font_get_glyph_extents (font, 2, &extents);
g_assert (result);
g_assert_cmpint (extents.x_bearing, ==, 7);
g_assert_cmpint (extents.x_bearing, ==, 8);
g_assert_cmpint (extents.y_bearing, ==, 669);
g_assert_cmpint (extents.width, ==, 650);
g_assert_cmpint (extents.width, ==, 649);
g_assert_cmpint (extents.height, ==, -669);
hb_font_destroy (font);
@ -199,7 +199,7 @@ test_extents_cff2_vsindex_named_instance (void)
hb_bool_t result = hb_font_get_glyph_extents (font, 1, &extents);
g_assert (result);
g_assert_cmpint (extents.x_bearing, ==, 12);
g_assert_cmpint (extents.x_bearing, ==, 13);
g_assert_cmpint (extents.y_bearing, ==, 652);
g_assert_cmpint (extents.width, ==, 653);
g_assert_cmpint (extents.height, ==, -652);

Loading…
Cancel
Save