[subset] hook up the repacker to run if offset overflows are encountered during subsetting.
This commit is contained in:
parent
f4c78cc7dd
commit
6b1ea4cbe7
|
@ -136,7 +136,14 @@ struct hb_serialize_context_t
|
||||||
|
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
bool check_equal (T1 &&v1, T2 &&v2)
|
bool check_equal (T1 &&v1, T2 &&v2)
|
||||||
{ return check_success ((long long) v1 == (long long) v2); }
|
{
|
||||||
|
if ((long long) v1 != (long long) v2)
|
||||||
|
{
|
||||||
|
err_offset_overflow ();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
bool check_assign (T1 &v1, T2 &&v2)
|
bool check_assign (T1 &v1, T2 &&v2)
|
||||||
|
@ -400,6 +407,7 @@ struct hb_serialize_context_t
|
||||||
|
|
||||||
/* Following two functions exist to allow setting breakpoint on. */
|
/* Following two functions exist to allow setting breakpoint on. */
|
||||||
void err_ran_out_of_room () { this->ran_out_of_room = true; }
|
void err_ran_out_of_room () { this->ran_out_of_room = true; }
|
||||||
|
void err_offset_overflow () { this->offset_overflow = true; }
|
||||||
void err_other_error () { this->successful = false; }
|
void err_other_error () { this->successful = false; }
|
||||||
|
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
|
@ -520,7 +528,7 @@ struct hb_serialize_context_t
|
||||||
(char *) b.arrayZ, free);
|
(char *) b.arrayZ, free);
|
||||||
}
|
}
|
||||||
|
|
||||||
const hb_vector_t<object_t *>& object_graph()
|
const hb_vector_t<object_t *>& object_graph() const
|
||||||
{ return packed; }
|
{ return packed; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -537,6 +545,7 @@ struct hb_serialize_context_t
|
||||||
unsigned int debug_depth;
|
unsigned int debug_depth;
|
||||||
bool successful;
|
bool successful;
|
||||||
bool ran_out_of_room;
|
bool ran_out_of_room;
|
||||||
|
bool offset_overflow;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
#include "hb-ot-layout-gpos-table.hh"
|
#include "hb-ot-layout-gpos-table.hh"
|
||||||
#include "hb-ot-var-gvar-table.hh"
|
#include "hb-ot-var-gvar-table.hh"
|
||||||
#include "hb-ot-var-hvar-table.hh"
|
#include "hb-ot-var-hvar-table.hh"
|
||||||
|
#include "hb-repacker.hh"
|
||||||
|
|
||||||
|
|
||||||
static unsigned
|
static unsigned
|
||||||
|
@ -64,6 +65,32 @@ _plan_estimate_subset_table_size (hb_subset_plan_t *plan, unsigned table_len)
|
||||||
return 512 + (unsigned) (table_len * sqrt ((double) dst_glyphs / src_glyphs));
|
return 512 + (unsigned) (table_len * sqrt ((double) dst_glyphs / src_glyphs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Repack the serialization buffer if any offset overflows exist.
|
||||||
|
*/
|
||||||
|
static hb_blob_t*
|
||||||
|
_repack (const hb_serialize_context_t& c)
|
||||||
|
{
|
||||||
|
if (!c.offset_overflow)
|
||||||
|
return c.copy_blob ();
|
||||||
|
|
||||||
|
hb_vector_t<char> buf;
|
||||||
|
int buf_size = c.end - c.start;
|
||||||
|
if (unlikely (!buf.alloc (buf_size)))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
hb_serialize_context_t repacked ((void *) buf, buf_size);
|
||||||
|
hb_resolve_overflows (c.object_graph (), &repacked);
|
||||||
|
|
||||||
|
if (unlikely (repacked.ran_out_of_room || repacked.in_error () || repacked.offset_overflow))
|
||||||
|
// TODO(garretrieger): refactor so we can share the resize/retry logic with the subset
|
||||||
|
// portion.
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return repacked.copy_blob ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename TableType>
|
template<typename TableType>
|
||||||
static bool
|
static bool
|
||||||
_subset (hb_subset_plan_t *plan)
|
_subset (hb_subset_plan_t *plan)
|
||||||
|
@ -111,7 +138,8 @@ _subset (hb_subset_plan_t *plan)
|
||||||
{
|
{
|
||||||
if (needed)
|
if (needed)
|
||||||
{
|
{
|
||||||
hb_blob_t *dest_blob = serializer.copy_blob ();
|
hb_blob_t *dest_blob = _repack (serializer);
|
||||||
|
if (!dest_blob) return false;
|
||||||
DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c final subset table size: %u bytes.", HB_UNTAG (tag), dest_blob->length);
|
DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c final subset table size: %u bytes.", HB_UNTAG (tag), dest_blob->length);
|
||||||
result = c.plan->add_table (tag, dest_blob);
|
result = c.plan->add_table (tag, dest_blob);
|
||||||
hb_blob_destroy (dest_blob);
|
hb_blob_destroy (dest_blob);
|
||||||
|
|
Loading…
Reference in New Issue