Add in_range in hb_bytes_t to merge range_checker_t with it
This commit is contained in:
parent
7915c5d6fa
commit
3958f6fb23
|
@ -196,6 +196,15 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
|
||||||
const T *as () const
|
const T *as () const
|
||||||
{ return length < hb_null_size (T) ? &Null (T) : reinterpret_cast<const T *> (arrayZ); }
|
{ return length < hb_null_size (T) ? &Null (T) : reinterpret_cast<const T *> (arrayZ); }
|
||||||
|
|
||||||
|
template <typename T,
|
||||||
|
unsigned P = sizeof (Type),
|
||||||
|
hb_enable_if (P == 1)>
|
||||||
|
bool in_range (const T *p, unsigned int size = T::static_size) const
|
||||||
|
{
|
||||||
|
return ((const char *) p) >= arrayZ
|
||||||
|
&& ((const char *) p + size) <= arrayZ + length;
|
||||||
|
}
|
||||||
|
|
||||||
/* Only call if you allocated the underlying array using malloc() or similar. */
|
/* Only call if you allocated the underlying array using malloc() or similar. */
|
||||||
void free ()
|
void free ()
|
||||||
{ ::free ((void *) arrayZ); arrayZ = nullptr; length = 0; }
|
{ ::free ((void *) arrayZ); arrayZ = nullptr; length = 0; }
|
||||||
|
|
|
@ -360,9 +360,9 @@ struct glyf
|
||||||
{
|
{
|
||||||
typedef const CompositeGlyphChain *__item_t__;
|
typedef const CompositeGlyphChain *__item_t__;
|
||||||
composite_iter_t (hb_bytes_t glyph_, __item_t__ current_) :
|
composite_iter_t (hb_bytes_t glyph_, __item_t__ current_) :
|
||||||
glyph (glyph_), current (current_), checker (range_checker_t (glyph.arrayZ, glyph.length))
|
glyph (glyph_), current (current_)
|
||||||
{ if (!in_range (current)) current = nullptr; }
|
{ if (!in_range (current)) current = nullptr; }
|
||||||
composite_iter_t () : glyph (hb_bytes_t ()), current (nullptr), checker (range_checker_t (nullptr, 0)) {}
|
composite_iter_t () : glyph (hb_bytes_t ()), current (nullptr) {}
|
||||||
|
|
||||||
const CompositeGlyphChain &__item__ () const { return *current; }
|
const CompositeGlyphChain &__item__ () const { return *current; }
|
||||||
bool __more__ () const { return current; }
|
bool __more__ () const { return current; }
|
||||||
|
@ -380,14 +380,13 @@ struct glyf
|
||||||
|
|
||||||
bool in_range (const CompositeGlyphChain *composite) const
|
bool in_range (const CompositeGlyphChain *composite) const
|
||||||
{
|
{
|
||||||
return checker.in_range (composite, CompositeGlyphChain::min_size)
|
return glyph.in_range (composite, CompositeGlyphChain::min_size)
|
||||||
&& checker.in_range (composite, composite->get_size ());
|
&& glyph.in_range (composite, composite->get_size ());
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
hb_bytes_t glyph;
|
hb_bytes_t glyph;
|
||||||
__item_t__ current;
|
__item_t__ current;
|
||||||
range_checker_t checker;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Glyph
|
struct Glyph
|
||||||
|
@ -537,7 +536,7 @@ struct glyf
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static bool read_points (const HBUINT8 *&p /* IN/OUT */,
|
static bool read_points (const HBUINT8 *&p /* IN/OUT */,
|
||||||
contour_point_vector_t &points_ /* IN/OUT */,
|
contour_point_vector_t &points_ /* IN/OUT */,
|
||||||
const range_checker_t &checker)
|
const hb_bytes_t &bytes)
|
||||||
{
|
{
|
||||||
T coord_setter;
|
T coord_setter;
|
||||||
float v = 0;
|
float v = 0;
|
||||||
|
@ -546,7 +545,7 @@ struct glyf
|
||||||
uint8_t flag = points_[i].flag;
|
uint8_t flag = points_[i].flag;
|
||||||
if (coord_setter.is_short (flag))
|
if (coord_setter.is_short (flag))
|
||||||
{
|
{
|
||||||
if (unlikely (!checker.in_range (p))) return false;
|
if (unlikely (!bytes.in_range (p))) return false;
|
||||||
if (coord_setter.is_same (flag))
|
if (coord_setter.is_same (flag))
|
||||||
v += *p++;
|
v += *p++;
|
||||||
else
|
else
|
||||||
|
@ -556,7 +555,7 @@ struct glyf
|
||||||
{
|
{
|
||||||
if (!coord_setter.is_same (flag))
|
if (!coord_setter.is_same (flag))
|
||||||
{
|
{
|
||||||
if (unlikely (!checker.in_range ((const HBUINT16 *) p))) return false;
|
if (unlikely (!bytes.in_range ((const HBUINT16 *) p))) return false;
|
||||||
v += *(const HBINT16 *) p;
|
v += *(const HBINT16 *) p;
|
||||||
p += HBINT16::static_size;
|
p += HBINT16::static_size;
|
||||||
}
|
}
|
||||||
|
@ -571,9 +570,8 @@ struct glyf
|
||||||
const bool phantom_only=false) const
|
const bool phantom_only=false) const
|
||||||
{
|
{
|
||||||
const HBUINT16 *endPtsOfContours = &StructAfter<HBUINT16> (header);
|
const HBUINT16 *endPtsOfContours = &StructAfter<HBUINT16> (header);
|
||||||
range_checker_t checker (bytes.arrayZ, bytes.length);
|
|
||||||
int num_contours = header.numberOfContours;
|
int num_contours = header.numberOfContours;
|
||||||
if (unlikely (!checker.in_range (&endPtsOfContours[num_contours + 1]))) return false;
|
if (unlikely (!bytes.in_range (&endPtsOfContours[num_contours + 1]))) return false;
|
||||||
unsigned int num_points = endPtsOfContours[num_contours - 1] + 1;
|
unsigned int num_points = endPtsOfContours[num_contours - 1] + 1;
|
||||||
|
|
||||||
points_.resize (num_points + PHANTOM_COUNT);
|
points_.resize (num_points + PHANTOM_COUNT);
|
||||||
|
@ -593,12 +591,12 @@ struct glyf
|
||||||
/* Read flags */
|
/* Read flags */
|
||||||
for (unsigned int i = 0; i < num_points; i++)
|
for (unsigned int i = 0; i < num_points; i++)
|
||||||
{
|
{
|
||||||
if (unlikely (!checker.in_range (p))) return false;
|
if (unlikely (!bytes.in_range (p))) return false;
|
||||||
uint8_t flag = *p++;
|
uint8_t flag = *p++;
|
||||||
points_[i].flag = flag;
|
points_[i].flag = flag;
|
||||||
if (flag & FLAG_REPEAT)
|
if (flag & FLAG_REPEAT)
|
||||||
{
|
{
|
||||||
if (unlikely (!checker.in_range (p))) return false;
|
if (unlikely (!bytes.in_range (p))) return false;
|
||||||
unsigned int repeat_count = *p++;
|
unsigned int repeat_count = *p++;
|
||||||
while ((repeat_count-- > 0) && (++i < num_points))
|
while ((repeat_count-- > 0) && (++i < num_points))
|
||||||
points_[i].flag = flag;
|
points_[i].flag = flag;
|
||||||
|
@ -606,8 +604,8 @@ struct glyf
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read x & y coordinates */
|
/* Read x & y coordinates */
|
||||||
return (read_points<x_setter_t> (p, points_, checker) &&
|
return (read_points<x_setter_t> (p, points_, bytes) &&
|
||||||
read_points<y_setter_t> (p, points_, checker));
|
read_points<y_setter_t> (p, points_, bytes));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -949,7 +947,7 @@ struct glyf
|
||||||
|
|
||||||
bool get_extents_var (hb_font_t *font, hb_codepoint_t gid,
|
bool get_extents_var (hb_font_t *font, hb_codepoint_t gid,
|
||||||
hb_glyph_extents_t *extents) const
|
hb_glyph_extents_t *extents) const
|
||||||
{ return get_var_extents_and_phantoms (font, gid, extents); }
|
{ return get_var_extents_and_phantoms (font, gid, extents); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -78,23 +78,6 @@ struct contour_point_vector_t : hb_vector_t<contour_point_t>
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct range_checker_t
|
|
||||||
{
|
|
||||||
range_checker_t (const void *data_, unsigned int length_)
|
|
||||||
: data ((const char *) data_), length (length_) {}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
bool in_range (const T *p, unsigned int size = T::static_size) const
|
|
||||||
{
|
|
||||||
return ((const char *) p) >= data
|
|
||||||
&& ((const char *) p + size) <= data + length;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const char *data;
|
|
||||||
const unsigned int length;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Tuple : UnsizedArrayOf<F2DOT14> {};
|
struct Tuple : UnsizedArrayOf<F2DOT14> {};
|
||||||
|
|
||||||
struct TuppleIndex : HBUINT16
|
struct TuppleIndex : HBUINT16
|
||||||
|
@ -233,10 +216,10 @@ struct GlyphVarData
|
||||||
{
|
{
|
||||||
if (var_data->has_shared_point_numbers ())
|
if (var_data->has_shared_point_numbers ())
|
||||||
{
|
{
|
||||||
range_checker_t checker (var_data, length);
|
hb_bytes_t bytes ((const char *) var_data, length);
|
||||||
const HBUINT8 *base = &(var_data+var_data->data);
|
const HBUINT8 *base = &(var_data+var_data->data);
|
||||||
const HBUINT8 *p = base;
|
const HBUINT8 *p = base;
|
||||||
if (!unpack_points (p, shared_indices, checker)) return false;
|
if (!unpack_points (p, shared_indices, bytes)) return false;
|
||||||
data_offset = p - base;
|
data_offset = p - base;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -292,7 +275,7 @@ struct GlyphVarData
|
||||||
|
|
||||||
static bool unpack_points (const HBUINT8 *&p /* IN/OUT */,
|
static bool unpack_points (const HBUINT8 *&p /* IN/OUT */,
|
||||||
hb_vector_t<unsigned int> &points /* OUT */,
|
hb_vector_t<unsigned int> &points /* OUT */,
|
||||||
const range_checker_t &check)
|
const hb_bytes_t &bytes)
|
||||||
{
|
{
|
||||||
enum packed_point_flag_t
|
enum packed_point_flag_t
|
||||||
{
|
{
|
||||||
|
@ -300,12 +283,12 @@ struct GlyphVarData
|
||||||
POINT_RUN_COUNT_MASK = 0x7F
|
POINT_RUN_COUNT_MASK = 0x7F
|
||||||
};
|
};
|
||||||
|
|
||||||
if (unlikely (!check.in_range (p))) return false;
|
if (unlikely (!bytes.in_range (p))) return false;
|
||||||
|
|
||||||
uint16_t count = *p++;
|
uint16_t count = *p++;
|
||||||
if (count & POINTS_ARE_WORDS)
|
if (count & POINTS_ARE_WORDS)
|
||||||
{
|
{
|
||||||
if (unlikely (!check.in_range (p))) return false;
|
if (unlikely (!bytes.in_range (p))) return false;
|
||||||
count = ((count & POINT_RUN_COUNT_MASK) << 8) | *p++;
|
count = ((count & POINT_RUN_COUNT_MASK) << 8) | *p++;
|
||||||
}
|
}
|
||||||
points.resize (count);
|
points.resize (count);
|
||||||
|
@ -314,7 +297,7 @@ struct GlyphVarData
|
||||||
uint16_t i = 0;
|
uint16_t i = 0;
|
||||||
while (i < count)
|
while (i < count)
|
||||||
{
|
{
|
||||||
if (unlikely (!check.in_range (p))) return false;
|
if (unlikely (!bytes.in_range (p))) return false;
|
||||||
uint16_t j;
|
uint16_t j;
|
||||||
uint8_t control = *p++;
|
uint8_t control = *p++;
|
||||||
uint16_t run_count = (control & POINT_RUN_COUNT_MASK) + 1;
|
uint16_t run_count = (control & POINT_RUN_COUNT_MASK) + 1;
|
||||||
|
@ -322,7 +305,7 @@ struct GlyphVarData
|
||||||
{
|
{
|
||||||
for (j = 0; j < run_count && i < count; j++, i++)
|
for (j = 0; j < run_count && i < count; j++, i++)
|
||||||
{
|
{
|
||||||
if (unlikely (!check.in_range ((const HBUINT16 *) p)))
|
if (unlikely (!bytes.in_range ((const HBUINT16 *) p)))
|
||||||
return false;
|
return false;
|
||||||
n += *(const HBUINT16 *)p;
|
n += *(const HBUINT16 *)p;
|
||||||
points[i] = n;
|
points[i] = n;
|
||||||
|
@ -333,7 +316,7 @@ struct GlyphVarData
|
||||||
{
|
{
|
||||||
for (j = 0; j < run_count && i < count; j++, i++)
|
for (j = 0; j < run_count && i < count; j++, i++)
|
||||||
{
|
{
|
||||||
if (unlikely (!check.in_range (p))) return false;
|
if (unlikely (!bytes.in_range (p))) return false;
|
||||||
n += *p++;
|
n += *p++;
|
||||||
points[i] = n;
|
points[i] = n;
|
||||||
}
|
}
|
||||||
|
@ -345,7 +328,7 @@ struct GlyphVarData
|
||||||
|
|
||||||
static bool unpack_deltas (const HBUINT8 *&p /* IN/OUT */,
|
static bool unpack_deltas (const HBUINT8 *&p /* IN/OUT */,
|
||||||
hb_vector_t<int> &deltas /* IN/OUT */,
|
hb_vector_t<int> &deltas /* IN/OUT */,
|
||||||
const range_checker_t &check)
|
const hb_bytes_t &bytes)
|
||||||
{
|
{
|
||||||
enum packed_delta_flag_t
|
enum packed_delta_flag_t
|
||||||
{
|
{
|
||||||
|
@ -358,7 +341,7 @@ struct GlyphVarData
|
||||||
unsigned int count = deltas.length;
|
unsigned int count = deltas.length;
|
||||||
while (i < count)
|
while (i < count)
|
||||||
{
|
{
|
||||||
if (unlikely (!check.in_range (p))) return false;
|
if (unlikely (!bytes.in_range (p))) return false;
|
||||||
uint8_t control = *p++;
|
uint8_t control = *p++;
|
||||||
unsigned int run_count = (control & DELTA_RUN_COUNT_MASK) + 1;
|
unsigned int run_count = (control & DELTA_RUN_COUNT_MASK) + 1;
|
||||||
unsigned int j;
|
unsigned int j;
|
||||||
|
@ -368,7 +351,7 @@ struct GlyphVarData
|
||||||
else if (control & DELTAS_ARE_WORDS)
|
else if (control & DELTAS_ARE_WORDS)
|
||||||
for (j = 0; j < run_count && i < count; j++, i++)
|
for (j = 0; j < run_count && i < count; j++, i++)
|
||||||
{
|
{
|
||||||
if (unlikely (!check.in_range ((const HBUINT16 *) p)))
|
if (unlikely (!bytes.in_range ((const HBUINT16 *) p)))
|
||||||
return false;
|
return false;
|
||||||
deltas[i] = *(const HBINT16 *) p;
|
deltas[i] = *(const HBINT16 *) p;
|
||||||
p += HBUINT16::static_size;
|
p += HBUINT16::static_size;
|
||||||
|
@ -376,7 +359,7 @@ struct GlyphVarData
|
||||||
else
|
else
|
||||||
for (j = 0; j < run_count && i < count; j++, i++)
|
for (j = 0; j < run_count && i < count; j++, i++)
|
||||||
{
|
{
|
||||||
if (unlikely (!check.in_range (p)))
|
if (unlikely (!bytes.in_range (p)))
|
||||||
return false;
|
return false;
|
||||||
deltas[i] = *(const HBINT8 *) p++;
|
deltas[i] = *(const HBINT8 *) p++;
|
||||||
}
|
}
|
||||||
|
@ -611,10 +594,10 @@ struct gvar
|
||||||
if (unlikely (!iterator.in_range (p, length)))
|
if (unlikely (!iterator.in_range (p, length)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
range_checker_t checker (p, length);
|
hb_bytes_t bytes ((const char *) p, length);
|
||||||
hb_vector_t<unsigned int> private_indices;
|
hb_vector_t<unsigned int> private_indices;
|
||||||
if (iterator.current_tuple->has_private_points () &&
|
if (iterator.current_tuple->has_private_points () &&
|
||||||
!GlyphVarData::unpack_points (p, private_indices, checker))
|
!GlyphVarData::unpack_points (p, private_indices, bytes))
|
||||||
return false;
|
return false;
|
||||||
const hb_array_t<unsigned int> &indices = private_indices.length ? private_indices : shared_indices;
|
const hb_array_t<unsigned int> &indices = private_indices.length ? private_indices : shared_indices;
|
||||||
|
|
||||||
|
@ -622,11 +605,11 @@ struct gvar
|
||||||
unsigned int num_deltas = apply_to_all ? points.length : indices.length;
|
unsigned int num_deltas = apply_to_all ? points.length : indices.length;
|
||||||
hb_vector_t<int> x_deltas;
|
hb_vector_t<int> x_deltas;
|
||||||
x_deltas.resize (num_deltas);
|
x_deltas.resize (num_deltas);
|
||||||
if (!GlyphVarData::unpack_deltas (p, x_deltas, checker))
|
if (!GlyphVarData::unpack_deltas (p, x_deltas, bytes))
|
||||||
return false;
|
return false;
|
||||||
hb_vector_t<int> y_deltas;
|
hb_vector_t<int> y_deltas;
|
||||||
y_deltas.resize (num_deltas);
|
y_deltas.resize (num_deltas);
|
||||||
if (!GlyphVarData::unpack_deltas (p, y_deltas, checker))
|
if (!GlyphVarData::unpack_deltas (p, y_deltas, bytes))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < deltas.length; i++)
|
for (unsigned int i = 0; i < deltas.length; i++)
|
||||||
|
|
Loading…
Reference in New Issue