[subset] Hmtx/vmtx tables to use subset2 and new iterator frameworks

pull/1753/head
Qunxin Liu 6 years ago committed by Garret Rieger
parent 89a7a880a1
commit 209491fc37
  1. 115
      src/hb-ot-hmtx-table.hh
  2. 6
      src/hb-subset.cc

@ -86,74 +86,71 @@ struct hmtxvmtx
return result;
}
bool subset (hb_subset_plan_t *plan) const
template<typename Iterator,
hb_requires (hb_is_iterator (Iterator))>
void serialize (hb_serialize_context_t *c,
Iterator it,
unsigned num_advances)
{
typename T::accelerator_t _mtx;
_mtx.init (plan->source);
/* All the trailing glyphs with the same advance can use one LongMetric
* and just keep LSB */
unsigned int num_output_glyphs = plan->num_output_glyphs ();
unsigned int num_advances = _mtx.num_advances_for_subset (plan);
/* alloc the new table */
size_t dest_sz = num_advances * 4
+ (num_output_glyphs - num_advances) * 2;
void *dest = (void *) malloc (dest_sz);
if (unlikely (!dest))
{
return false;
}
DEBUG_MSG(SUBSET, nullptr, "%c%c%c%c in src has %d advances, %d lsbs", HB_UNTAG(T::tableTag), _mtx.num_advances, _mtx.num_metrics - _mtx.num_advances);
DEBUG_MSG(SUBSET, nullptr, "%c%c%c%c in dest has %d advances, %d lsbs, %u bytes",
HB_UNTAG(T::tableTag), num_advances, num_output_glyphs - num_advances, (unsigned int) dest_sz);
// Copy everything over
char * dest_pos = (char *) dest;
unsigned idx = 0;
+ it
| hb_apply ([c, &idx, num_advances] (const hb_item_type<Iterator>& _)
{
if (idx < num_advances)
{
LongMetric lm;
lm.advance = _.first;
lm.sb = _.second;
if (unlikely (!c->embed<LongMetric> (&lm))) return;
}
else
{
FWORD *sb = c->allocate_size<FWORD> (FWORD::static_size);
if (unlikely (!sb)) return;
*sb = _.second;
}
idx++;
})
;
}
bool failed = false;
for (unsigned int i = 0; i < num_output_glyphs; i++)
{
unsigned int side_bearing = 0;
unsigned int advance = 0;
hb_codepoint_t old_gid;
if (plan->old_gid_for_new_gid (i, &old_gid))
{
// Glyph is not an empty glyph so copy advance and side bearing
// from the input font.
side_bearing = _mtx.get_side_bearing (old_gid);
advance = _mtx.get_advance (old_gid);
}
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
T *table_prime = c->serializer->start_embed <T> ();
if (unlikely (!table_prime)) return_trace (false);
accelerator_t _mtx;
_mtx.init (c->plan->source);
unsigned num_advances = _mtx.num_advances_for_subset (c->plan);
auto it =
+ hb_range (c->plan->num_output_glyphs ())
| hb_map ([c, &_mtx] (unsigned _)
{
hb_codepoint_t old_gid;
if (c->plan->old_gid_for_new_gid (_, &old_gid))
return hb_pair (_mtx.get_advance (old_gid), _mtx.get_side_bearing (old_gid));
else
return hb_pair (0u, 0u);
})
;
table_prime->serialize (c->serializer, it, num_advances);
bool has_advance = i < num_advances;
if (has_advance)
{
((LongMetric *) dest_pos)->advance = advance;
((LongMetric *) dest_pos)->sb = side_bearing;
}
else
{
*((FWORD *) dest_pos) = side_bearing;
}
dest_pos += (has_advance ? 4 : 2);
}
_mtx.fini ();
if (unlikely (c->serializer->ran_out_of_room || c->serializer->in_error ()))
return_trace (false);
// Amend header num hmetrics
if (failed || unlikely (!subset_update_header (plan, num_advances)))
if (unlikely (!subset_update_header (c->plan, num_advances)))
{
free (dest);
return false;
return_trace (false);
}
hb_blob_t *result = hb_blob_create ((const char *)dest,
dest_sz,
HB_MEMORY_MODE_READONLY,
dest,
free);
bool success = plan->add_table (T::tableTag, result);
hb_blob_destroy (result);
return success;
return_trace (true);
}
struct accelerator_t

@ -67,7 +67,7 @@ template<typename TableType>
static bool
_subset2 (hb_subset_plan_t *plan)
{
bool result = true;
bool result = false;
hb_blob_t *source_blob = hb_sanitize_context_t ().reference_table<TableType> (plan->source);
const TableType *table = source_blob->as<TableType> ();
@ -172,13 +172,13 @@ _subset_table (hb_subset_plan_t *plan,
DEBUG_MSG(SUBSET, nullptr, "skip hhea handled by hmtx");
return true;
case HB_OT_TAG_hmtx:
result = _subset<const OT::hmtx> (plan);
result = _subset2<const OT::hmtx> (plan);
break;
case HB_OT_TAG_vhea:
DEBUG_MSG(SUBSET, nullptr, "skip vhea handled by vmtx");
return true;
case HB_OT_TAG_vmtx:
result = _subset<const OT::vmtx> (plan);
result = _subset2<const OT::vmtx> (plan);
break;
case HB_OT_TAG_maxp:
result = _subset<const OT::maxp> (plan);

Loading…
Cancel
Save