[subset] Add subset () method for COLRv1 Paint tables, BaseGlyphV1List and LayerV1List
Also add support for Offset24 in serializer and repacker
This commit is contained in:
parent
413769bf86
commit
b23f29bf05
|
@ -180,6 +180,15 @@ struct NoVariable
|
||||||
template <template<typename> class Var>
|
template <template<typename> class Var>
|
||||||
struct ColorIndex
|
struct ColorIndex
|
||||||
{
|
{
|
||||||
|
bool subset (hb_subset_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SUBSET (this);
|
||||||
|
auto *out = c->serializer->embed (*this);
|
||||||
|
if (unlikely (!out)) return_trace (false);
|
||||||
|
return_trace (c->serializer->check_assign (out->paletteIndex, c->plan->colrv1_palettes->get (paletteIndex),
|
||||||
|
HB_SERIALIZE_ERROR_INT_OVERFLOW));
|
||||||
|
}
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
|
@ -195,6 +204,13 @@ struct ColorIndex
|
||||||
template <template<typename> class Var>
|
template <template<typename> class Var>
|
||||||
struct ColorStop
|
struct ColorStop
|
||||||
{
|
{
|
||||||
|
bool subset (hb_subset_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SUBSET (this);
|
||||||
|
if (unlikely (!c->serializer->embed (stopOffset))) return_trace (false);
|
||||||
|
return_trace (color.subset (c));
|
||||||
|
}
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
|
@ -221,6 +237,23 @@ struct Extend : HBUINT8
|
||||||
template <template<typename> class Var>
|
template <template<typename> class Var>
|
||||||
struct ColorLine
|
struct ColorLine
|
||||||
{
|
{
|
||||||
|
bool subset (hb_subset_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SUBSET (this);
|
||||||
|
auto *out = c->serializer->start_embed (this);
|
||||||
|
if (unlikely (!out)) return_trace (false);
|
||||||
|
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
|
||||||
|
|
||||||
|
if (!c->serializer->check_assign (out->extend, extend, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false);
|
||||||
|
if (!c->serializer->check_assign (out->stops.len, stops.len, HB_SERIALIZE_ERROR_ARRAY_OVERFLOW)) return_trace (false);
|
||||||
|
|
||||||
|
for (const auto& stop : stops.iter ())
|
||||||
|
{
|
||||||
|
if (!stop.subset (c)) return_trace (false);
|
||||||
|
}
|
||||||
|
return_trace (true);
|
||||||
|
}
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
|
@ -306,6 +339,17 @@ struct PaintColrLayers
|
||||||
{
|
{
|
||||||
void closurev1 (hb_colrv1_closure_context_t* c) const;
|
void closurev1 (hb_colrv1_closure_context_t* c) const;
|
||||||
|
|
||||||
|
bool subset (hb_subset_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SUBSET (this);
|
||||||
|
auto *out = c->serializer->embed (this);
|
||||||
|
if (unlikely (!out)) return_trace (false);
|
||||||
|
return_trace (c->serializer->check_assign (out->firstLayerIndex, c->plan->colrv1_layers->get (firstLayerIndex),
|
||||||
|
HB_SERIALIZE_ERROR_INT_OVERFLOW));
|
||||||
|
|
||||||
|
return_trace (true);
|
||||||
|
}
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
|
@ -325,6 +369,13 @@ struct PaintSolid
|
||||||
void closurev1 (hb_colrv1_closure_context_t* c) const
|
void closurev1 (hb_colrv1_closure_context_t* c) const
|
||||||
{ c->add_palette_index (color.paletteIndex); }
|
{ c->add_palette_index (color.paletteIndex); }
|
||||||
|
|
||||||
|
bool subset (hb_subset_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SUBSET (this);
|
||||||
|
if (unlikely (!c->serializer->embed (format))) return_trace (false);
|
||||||
|
return_trace (color.subset (c));
|
||||||
|
}
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
|
@ -346,6 +397,15 @@ struct PaintLinearGradient
|
||||||
c->add_palette_index (stop.color.paletteIndex);
|
c->add_palette_index (stop.color.paletteIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool subset (hb_subset_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SUBSET (this);
|
||||||
|
auto *out = c->serializer->embed (this);
|
||||||
|
if (unlikely (!out)) return_trace (false);
|
||||||
|
|
||||||
|
return_trace (out->colorLine.serialize_subset (c, colorLine, this));
|
||||||
|
}
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
|
@ -368,6 +428,15 @@ struct PaintLinearGradient
|
||||||
template <template<typename> class Var>
|
template <template<typename> class Var>
|
||||||
struct PaintRadialGradient
|
struct PaintRadialGradient
|
||||||
{
|
{
|
||||||
|
bool subset (hb_subset_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SUBSET (this);
|
||||||
|
auto *out = c->serializer->embed (this);
|
||||||
|
if (unlikely (!out)) return_trace (false);
|
||||||
|
|
||||||
|
return_trace (out->colorLine.serialize_subset (c, colorLine, this));
|
||||||
|
}
|
||||||
|
|
||||||
void closurev1 (hb_colrv1_closure_context_t* c) const
|
void closurev1 (hb_colrv1_closure_context_t* c) const
|
||||||
{
|
{
|
||||||
for (const auto &stop : (this+colorLine).stops.iter ())
|
for (const auto &stop : (this+colorLine).stops.iter ())
|
||||||
|
@ -396,6 +465,15 @@ struct PaintRadialGradient
|
||||||
template <template<typename> class Var>
|
template <template<typename> class Var>
|
||||||
struct PaintSweepGradient
|
struct PaintSweepGradient
|
||||||
{
|
{
|
||||||
|
bool subset (hb_subset_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SUBSET (this);
|
||||||
|
auto *out = c->serializer->embed (this);
|
||||||
|
if (unlikely (!out)) return_trace (false);
|
||||||
|
|
||||||
|
return_trace (out->colorLine.serialize_subset (c, colorLine, this));
|
||||||
|
}
|
||||||
|
|
||||||
void closurev1 (hb_colrv1_closure_context_t* c) const
|
void closurev1 (hb_colrv1_closure_context_t* c) const
|
||||||
{
|
{
|
||||||
for (const auto &stop : (this+colorLine).stops.iter ())
|
for (const auto &stop : (this+colorLine).stops.iter ())
|
||||||
|
@ -425,6 +503,19 @@ struct PaintGlyph
|
||||||
{
|
{
|
||||||
void closurev1 (hb_colrv1_closure_context_t* c) const;
|
void closurev1 (hb_colrv1_closure_context_t* c) const;
|
||||||
|
|
||||||
|
bool subset (hb_subset_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SUBSET (this);
|
||||||
|
auto *out = c->serializer->embed (this);
|
||||||
|
if (unlikely (!out)) return_trace (false);
|
||||||
|
|
||||||
|
if (! c->serializer->check_assign (out->gid, c->plan->glyph_map->get (gid),
|
||||||
|
HB_SERIALIZE_ERROR_INT_OVERFLOW))
|
||||||
|
return_trace (false);
|
||||||
|
|
||||||
|
return_trace (out->paint.serialize_subset (c, paint, this));
|
||||||
|
}
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
|
@ -442,6 +533,16 @@ struct PaintColrGlyph
|
||||||
{
|
{
|
||||||
void closurev1 (hb_colrv1_closure_context_t* c) const;
|
void closurev1 (hb_colrv1_closure_context_t* c) const;
|
||||||
|
|
||||||
|
bool subset (hb_subset_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SUBSET (this);
|
||||||
|
auto *out = c->serializer->embed (this);
|
||||||
|
if (unlikely (!out)) return_trace (false);
|
||||||
|
|
||||||
|
return_trace (c->serializer->check_assign (out->gid, c->plan->glyph_map->get (gid),
|
||||||
|
HB_SERIALIZE_ERROR_INT_OVERFLOW));
|
||||||
|
}
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
|
@ -459,6 +560,15 @@ struct PaintTransform
|
||||||
{
|
{
|
||||||
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
|
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
|
||||||
|
|
||||||
|
bool subset (hb_subset_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SUBSET (this);
|
||||||
|
auto *out = c->serializer->embed (this);
|
||||||
|
if (unlikely (!out)) return_trace (false);
|
||||||
|
|
||||||
|
return_trace (out->src.serialize_subset (c, src, this));
|
||||||
|
}
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
|
@ -477,6 +587,15 @@ struct PaintTranslate
|
||||||
{
|
{
|
||||||
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
|
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
|
||||||
|
|
||||||
|
bool subset (hb_subset_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SUBSET (this);
|
||||||
|
auto *out = c->serializer->embed (this);
|
||||||
|
if (unlikely (!out)) return_trace (false);
|
||||||
|
|
||||||
|
return_trace (out->src.serialize_subset (c, src, this));
|
||||||
|
}
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
|
@ -496,6 +615,15 @@ struct PaintRotate
|
||||||
{
|
{
|
||||||
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
|
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
|
||||||
|
|
||||||
|
bool subset (hb_subset_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SUBSET (this);
|
||||||
|
auto *out = c->serializer->embed (this);
|
||||||
|
if (unlikely (!out)) return_trace (false);
|
||||||
|
|
||||||
|
return_trace (out->src.serialize_subset (c, src, this));
|
||||||
|
}
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
|
@ -516,6 +644,15 @@ struct PaintSkew
|
||||||
{
|
{
|
||||||
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
|
HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
|
||||||
|
|
||||||
|
bool subset (hb_subset_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SUBSET (this);
|
||||||
|
auto *out = c->serializer->embed (this);
|
||||||
|
if (unlikely (!out)) return_trace (false);
|
||||||
|
|
||||||
|
return_trace (out->src.serialize_subset (c, src, this));
|
||||||
|
}
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
|
@ -536,6 +673,16 @@ struct PaintComposite
|
||||||
{
|
{
|
||||||
void closurev1 (hb_colrv1_closure_context_t* c) const;
|
void closurev1 (hb_colrv1_closure_context_t* c) const;
|
||||||
|
|
||||||
|
bool subset (hb_subset_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SUBSET (this);
|
||||||
|
auto *out = c->serializer->embed (this);
|
||||||
|
if (unlikely (!out)) return_trace (false);
|
||||||
|
|
||||||
|
if (!out->src.serialize_subset (c, src, this)) return_trace (false);
|
||||||
|
return_trace (out->backdrop.serialize_subset (c, backdrop, this));
|
||||||
|
}
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
|
@ -615,6 +762,19 @@ struct BaseGlyphV1Record
|
||||||
int cmp (hb_codepoint_t g) const
|
int cmp (hb_codepoint_t g) const
|
||||||
{ return g < glyphId ? -1 : g > glyphId ? 1 : 0; }
|
{ return g < glyphId ? -1 : g > glyphId ? 1 : 0; }
|
||||||
|
|
||||||
|
bool serialize (hb_serialize_context_t *s, const hb_map_t* glyph_map,
|
||||||
|
const void* src_base, hb_subset_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SERIALIZE (this);
|
||||||
|
auto *out = s->embed (this);
|
||||||
|
if (unlikely (!out)) return_trace (false);
|
||||||
|
if (!s->check_assign (out->glyphId, glyph_map->get (glyphId),
|
||||||
|
HB_SERIALIZE_ERROR_INT_OVERFLOW))
|
||||||
|
return_trace (false);
|
||||||
|
|
||||||
|
return_trace (out->paint.serialize_subset (c, paint, src_base));
|
||||||
|
}
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
|
@ -629,13 +789,47 @@ struct BaseGlyphV1Record
|
||||||
DEFINE_SIZE_STATIC (6);
|
DEFINE_SIZE_STATIC (6);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef SortedArray32Of<BaseGlyphV1Record> BaseGlyphV1List;
|
struct BaseGlyphV1List : SortedArray32Of<BaseGlyphV1Record>
|
||||||
|
{
|
||||||
|
bool subset (hb_subset_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SUBSET (this);
|
||||||
|
auto *out = c->serializer->start_embed (this);
|
||||||
|
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
|
||||||
|
const hb_set_t* glyphset = c->plan->_glyphset;
|
||||||
|
|
||||||
|
for (const auto& _ : as_array ())
|
||||||
|
{
|
||||||
|
unsigned gid = _.glyphId;
|
||||||
|
if (!glyphset->has (gid)) continue;
|
||||||
|
|
||||||
|
if (_.serialize (c->serializer, c->plan->glyph_map, this, c)) out->len++;
|
||||||
|
else return_trace (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return_trace (true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct LayerV1List : Array32OfOffset32To<Paint>
|
struct LayerV1List : Array32OfOffset32To<Paint>
|
||||||
{
|
{
|
||||||
const Paint& get_paint (unsigned i) const
|
const Paint& get_paint (unsigned i) const
|
||||||
{ return this+(*this)[i]; }
|
{ return this+(*this)[i]; }
|
||||||
|
|
||||||
|
bool subset (hb_subset_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SUBSET (this);
|
||||||
|
auto *out = c->serializer->start_embed (this);
|
||||||
|
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
|
||||||
|
|
||||||
|
for (const auto& offset : as_array ()) {
|
||||||
|
auto *o = out->serialize_append (c->serializer);
|
||||||
|
if (unlikely (!o) || !o->serialize_subset (c, offset, this))
|
||||||
|
return_trace (false);
|
||||||
|
}
|
||||||
|
return_trace (true);
|
||||||
|
}
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
|
|
|
@ -531,7 +531,7 @@ struct graph_t
|
||||||
|
|
||||||
const auto& child = vertices_[link.objidx].obj;
|
const auto& child = vertices_[link.objidx].obj;
|
||||||
int64_t child_weight = child.tail - child.head +
|
int64_t child_weight = child.tail - child.head +
|
||||||
(!link.is_wide ? (1 << 16) : ((int64_t) 1 << 32));
|
((int64_t) 1 << (link.width * 8));
|
||||||
int64_t child_distance = next_distance + child_weight;
|
int64_t child_distance = next_distance + child_weight;
|
||||||
|
|
||||||
if (child_distance < vertices_[link.objidx].distance)
|
if (child_distance < vertices_[link.objidx].distance)
|
||||||
|
@ -578,15 +578,17 @@ struct graph_t
|
||||||
{
|
{
|
||||||
if (link.is_signed)
|
if (link.is_signed)
|
||||||
{
|
{
|
||||||
if (link.is_wide)
|
if (link.width == 4)
|
||||||
return offset >= -((int64_t) 1 << 31) && offset < ((int64_t) 1 << 31);
|
return offset >= -((int64_t) 1 << 31) && offset < ((int64_t) 1 << 31);
|
||||||
else
|
else
|
||||||
return offset >= -(1 << 15) && offset < (1 << 15);
|
return offset >= -(1 << 15) && offset < (1 << 15);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (link.is_wide)
|
if (link.width == 4)
|
||||||
return offset >= 0 && offset < ((int64_t) 1 << 32);
|
return offset >= 0 && offset < ((int64_t) 1 << 32);
|
||||||
|
else if (link.width == 3)
|
||||||
|
return offset >= 0 && offset < ((int32_t) 1 << 24);
|
||||||
else
|
else
|
||||||
return offset >= 0 && offset < (1 << 16);
|
return offset >= 0 && offset < (1 << 16);
|
||||||
}
|
}
|
||||||
|
@ -627,7 +629,7 @@ struct graph_t
|
||||||
char* head,
|
char* head,
|
||||||
hb_serialize_context_t* c) const
|
hb_serialize_context_t* c) const
|
||||||
{
|
{
|
||||||
if (link.is_wide)
|
if (link.width == 4)
|
||||||
{
|
{
|
||||||
if (link.is_signed)
|
if (link.is_signed)
|
||||||
{
|
{
|
||||||
|
@ -635,7 +637,9 @@ struct graph_t
|
||||||
} else {
|
} else {
|
||||||
serialize_link_of_type<OT::HBUINT32> (link, head, c);
|
serialize_link_of_type<OT::HBUINT32> (link, head, c);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else if (link.width == 2)
|
||||||
|
{
|
||||||
if (link.is_signed)
|
if (link.is_signed)
|
||||||
{
|
{
|
||||||
serialize_link_of_type<OT::HBINT16> (link, head, c);
|
serialize_link_of_type<OT::HBINT16> (link, head, c);
|
||||||
|
@ -643,6 +647,8 @@ struct graph_t
|
||||||
serialize_link_of_type<OT::HBUINT16> (link, head, c);
|
serialize_link_of_type<OT::HBUINT16> (link, head, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
serialize_link_of_type<OT::HBUINT24> (link, head, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -82,7 +82,7 @@ struct hb_serialize_context_t
|
||||||
|
|
||||||
struct link_t
|
struct link_t
|
||||||
{
|
{
|
||||||
bool is_wide: 1;
|
unsigned width: 3;
|
||||||
bool is_signed: 1;
|
bool is_signed: 1;
|
||||||
unsigned whence: 2;
|
unsigned whence: 2;
|
||||||
unsigned position: 28;
|
unsigned position: 28;
|
||||||
|
@ -354,7 +354,6 @@ struct hb_serialize_context_t
|
||||||
whence_t whence = Head,
|
whence_t whence = Head,
|
||||||
unsigned bias = 0)
|
unsigned bias = 0)
|
||||||
{
|
{
|
||||||
static_assert (sizeof (T) == 2 || sizeof (T) == 4, "");
|
|
||||||
if (unlikely (in_error ())) return;
|
if (unlikely (in_error ())) return;
|
||||||
|
|
||||||
if (!objidx)
|
if (!objidx)
|
||||||
|
@ -365,7 +364,7 @@ struct hb_serialize_context_t
|
||||||
|
|
||||||
auto& link = *current->links.push ();
|
auto& link = *current->links.push ();
|
||||||
|
|
||||||
link.is_wide = sizeof (T) == 4;
|
link.width = sizeof (T);
|
||||||
link.is_signed = hb_is_signed (hb_unwrap_type (T));
|
link.is_signed = hb_is_signed (hb_unwrap_type (T));
|
||||||
link.whence = (unsigned) whence;
|
link.whence = (unsigned) whence;
|
||||||
link.position = (const char *) &ofs - current->head;
|
link.position = (const char *) &ofs - current->head;
|
||||||
|
@ -405,15 +404,19 @@ struct hb_serialize_context_t
|
||||||
offset -= link.bias;
|
offset -= link.bias;
|
||||||
if (link.is_signed)
|
if (link.is_signed)
|
||||||
{
|
{
|
||||||
if (link.is_wide)
|
assert (link.width == 2 || link.width == 4);
|
||||||
|
if (link.width == 4)
|
||||||
assign_offset<int32_t> (parent, link, offset);
|
assign_offset<int32_t> (parent, link, offset);
|
||||||
else
|
else
|
||||||
assign_offset<int16_t> (parent, link, offset);
|
assign_offset<int16_t> (parent, link, offset);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (link.is_wide)
|
assert (link.width == 2 || link.width == 3 || link.width == 4);
|
||||||
|
if (link.width == 4)
|
||||||
assign_offset<uint32_t> (parent, link, offset);
|
assign_offset<uint32_t> (parent, link, offset);
|
||||||
|
else if (link.width == 3)
|
||||||
|
assign_offset<uint32_t, 3> (parent, link, offset);
|
||||||
else
|
else
|
||||||
assign_offset<uint16_t> (parent, link, offset);
|
assign_offset<uint16_t> (parent, link, offset);
|
||||||
}
|
}
|
||||||
|
@ -566,10 +569,10 @@ struct hb_serialize_context_t
|
||||||
{ return packed; }
|
{ return packed; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename T>
|
template <typename T, unsigned Size = sizeof (T)>
|
||||||
void assign_offset (const object_t* parent, const object_t::link_t &link, unsigned offset)
|
void assign_offset (const object_t* parent, const object_t::link_t &link, unsigned offset)
|
||||||
{
|
{
|
||||||
auto &off = * ((BEInt<T> *) (parent->head + link.position));
|
auto &off = * ((BEInt<T, Size> *) (parent->head + link.position));
|
||||||
assert (0 == off);
|
assert (0 == off);
|
||||||
check_assign (off, offset, HB_SERIALIZE_ERROR_OFFSET_OVERFLOW);
|
check_assign (off, offset, HB_SERIALIZE_ERROR_OFFSET_OVERFLOW);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue