[cff] Use switch on multi-format structs (#1762)
This commit is contained in:
parent
eff579f743
commit
9b853f755d
|
@ -76,8 +76,8 @@ struct biased_subrs_t
|
||||||
|
|
||||||
void fini () {}
|
void fini () {}
|
||||||
|
|
||||||
unsigned int get_count () const { return (subrs == nullptr)? 0: subrs->count; }
|
unsigned int get_count () const { return (subrs == nullptr) ? 0 : subrs->count; }
|
||||||
unsigned int get_bias () const { return bias; }
|
unsigned int get_bias () const { return bias; }
|
||||||
|
|
||||||
byte_str_t operator [] (unsigned int index) const
|
byte_str_t operator [] (unsigned int index) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -134,10 +134,10 @@ struct dict_opset_t : opset_t<number_t>
|
||||||
return value;
|
return value;
|
||||||
|
|
||||||
case END:
|
case END:
|
||||||
value = (double)(neg? -int_part: int_part);
|
value = (double) (neg ? -int_part : int_part);
|
||||||
if (frac_count > 0)
|
if (frac_count > 0)
|
||||||
{
|
{
|
||||||
double frac = (frac_part / pow (10.0, (double)frac_count));
|
double frac = (frac_part / pow (10.0, (double) frac_count));
|
||||||
if (neg) frac = -frac;
|
if (neg) frac = -frac;
|
||||||
value += frac;
|
value += frac;
|
||||||
}
|
}
|
||||||
|
@ -146,16 +146,16 @@ struct dict_opset_t : opset_t<number_t>
|
||||||
if (value == 0.0)
|
if (value == 0.0)
|
||||||
return value;
|
return value;
|
||||||
if (exp_neg)
|
if (exp_neg)
|
||||||
return neg? -DBL_MIN: DBL_MIN;
|
return neg ? -DBL_MIN : DBL_MIN;
|
||||||
else
|
else
|
||||||
return neg? -DBL_MAX: DBL_MAX;
|
return neg ? -DBL_MAX : DBL_MAX;
|
||||||
}
|
}
|
||||||
if (exp_part != 0)
|
if (exp_part != 0)
|
||||||
{
|
{
|
||||||
if (exp_neg)
|
if (exp_neg)
|
||||||
value /= pow (10.0, (double)exp_part);
|
value /= pow (10.0, (double) exp_part);
|
||||||
else
|
else
|
||||||
value *= pow (10.0, (double)exp_part);
|
value *= pow (10.0, (double) exp_part);
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
|
|
||||||
|
|
|
@ -82,22 +82,14 @@ struct str_buff_vec_t : hb_vector_t<str_buff_t>
|
||||||
template <typename COUNT>
|
template <typename COUNT>
|
||||||
struct CFFIndex
|
struct CFFIndex
|
||||||
{
|
{
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
|
||||||
{
|
|
||||||
TRACE_SANITIZE (this);
|
|
||||||
return_trace (likely ((count.sanitize (c) && count == 0) || /* empty INDEX */
|
|
||||||
(c->check_struct (this) && offSize >= 1 && offSize <= 4 &&
|
|
||||||
c->check_array (offsets, offSize, count + 1) &&
|
|
||||||
c->check_array ((const HBUINT8*)data_base (), 1, max_offset () - 1))));
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int calculate_offset_array_size (unsigned int offSize, unsigned int count)
|
static unsigned int calculate_offset_array_size (unsigned int offSize, unsigned int count)
|
||||||
{ return offSize * (count + 1); }
|
{ return offSize * (count + 1); }
|
||||||
|
|
||||||
unsigned int offset_array_size () const
|
unsigned int offset_array_size () const
|
||||||
{ return calculate_offset_array_size (offSize, count); }
|
{ return calculate_offset_array_size (offSize, count); }
|
||||||
|
|
||||||
static unsigned int calculate_serialized_size (unsigned int offSize_, unsigned int count, unsigned int dataSize)
|
static unsigned int calculate_serialized_size (unsigned int offSize_, unsigned int count,
|
||||||
|
unsigned int dataSize)
|
||||||
{
|
{
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
return COUNT::static_size;
|
return COUNT::static_size;
|
||||||
|
@ -199,11 +191,11 @@ struct CFFIndex
|
||||||
|
|
||||||
unsigned int length_at (unsigned int index) const
|
unsigned int length_at (unsigned int index) const
|
||||||
{
|
{
|
||||||
if (likely ((offset_at (index + 1) >= offset_at (index)) &&
|
if (likely ((offset_at (index + 1) >= offset_at (index)) &&
|
||||||
(offset_at (index + 1) <= offset_at (count))))
|
(offset_at (index + 1) <= offset_at (count))))
|
||||||
return offset_at (index + 1) - offset_at (index);
|
return offset_at (index + 1) - offset_at (index);
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned char *data_base () const
|
const unsigned char *data_base () const
|
||||||
|
@ -216,12 +208,12 @@ struct CFFIndex
|
||||||
if (likely (index < count))
|
if (likely (index < count))
|
||||||
return byte_str_t (data_base () + offset_at (index) - 1, length_at (index));
|
return byte_str_t (data_base () + offset_at (index) - 1, length_at (index));
|
||||||
else
|
else
|
||||||
return Null(byte_str_t);
|
return Null (byte_str_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int get_size () const
|
unsigned int get_size () const
|
||||||
{
|
{
|
||||||
if (this != &Null(CFFIndex))
|
if (this != &Null (CFFIndex))
|
||||||
{
|
{
|
||||||
if (count > 0)
|
if (count > 0)
|
||||||
return min_size + offset_array_size () + (offset_at (count) - 1);
|
return min_size + offset_array_size () + (offset_at (count) - 1);
|
||||||
|
@ -232,6 +224,15 @@ struct CFFIndex
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SANITIZE (this);
|
||||||
|
return_trace (likely ((count.sanitize (c) && count == 0) || /* empty INDEX */
|
||||||
|
(c->check_struct (this) && offSize >= 1 && offSize <= 4 &&
|
||||||
|
c->check_array (offsets, offSize, count + 1) &&
|
||||||
|
c->check_array ((const HBUINT8*) data_base (), 1, max_offset () - 1))));
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
unsigned int max_offset () const
|
unsigned int max_offset () const
|
||||||
{
|
{
|
||||||
|
@ -245,10 +246,10 @@ struct CFFIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
COUNT count; /* Number of object data. Note there are (count+1) offsets */
|
COUNT count; /* Number of object data. Note there are (count+1) offsets */
|
||||||
HBUINT8 offSize; /* The byte size of each offset in the offsets array. */
|
HBUINT8 offSize; /* The byte size of each offset in the offsets array. */
|
||||||
HBUINT8 offsets[VAR]; /* The array of (count + 1) offsets into objects array (1-base). */
|
HBUINT8 offsets[VAR]; /* The array of (count + 1) offsets into objects array (1-base). */
|
||||||
/* HBUINT8 data[VAR]; Object data */
|
/* HBUINT8 data[VAR]; Object data */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_ARRAY (COUNT::static_size + HBUINT8::static_size, offsets);
|
DEFINE_SIZE_ARRAY (COUNT::static_size + HBUINT8::static_size, offsets);
|
||||||
};
|
};
|
||||||
|
@ -293,7 +294,7 @@ struct CFFIndexOf : CFFIndex<COUNT>
|
||||||
/* serialize data */
|
/* serialize data */
|
||||||
for (unsigned int i = 0; i < dataArrayLen; i++)
|
for (unsigned int i = 0; i < dataArrayLen; i++)
|
||||||
{
|
{
|
||||||
TYPE *dest = c->start_embed<TYPE> ();
|
TYPE *dest = c->start_embed<TYPE> ();
|
||||||
if (unlikely (dest == nullptr ||
|
if (unlikely (dest == nullptr ||
|
||||||
!dest->serialize (c, dataArray[i], param1, param2)))
|
!dest->serialize (c, dataArray[i], param1, param2)))
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
|
@ -310,7 +311,7 @@ struct CFFIndexOf : CFFIndex<COUNT>
|
||||||
const PARAM ¶m)
|
const PARAM ¶m)
|
||||||
{
|
{
|
||||||
/* determine offset size */
|
/* determine offset size */
|
||||||
unsigned int totalDataSize = 0;
|
unsigned int totalDataSize = 0;
|
||||||
for (unsigned int i = 0; i < dataArrayLen; i++)
|
for (unsigned int i = 0; i < dataArrayLen; i++)
|
||||||
{
|
{
|
||||||
unsigned int dataSize = TYPE::calculate_serialized_size (dataArray[i], param);
|
unsigned int dataSize = TYPE::calculate_serialized_size (dataArray[i], param);
|
||||||
|
@ -334,10 +335,9 @@ struct Dict : UnsizedByteStr
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
for (unsigned int i = 0; i < dictval.get_count (); i++)
|
for (unsigned int i = 0; i < dictval.get_count (); i++)
|
||||||
{
|
|
||||||
if (unlikely (!opszr.serialize (c, dictval[i], param)))
|
if (unlikely (!opszr.serialize (c, dictval[i], param)))
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
}
|
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,14 +391,10 @@ struct Dict : UnsizedByteStr
|
||||||
{ return serialize_int_op<HBUINT16, 0, 0x7FFF> (c, op, value, OpCode_shortint); }
|
{ return serialize_int_op<HBUINT16, 0, 0x7FFF> (c, op, value, OpCode_shortint); }
|
||||||
|
|
||||||
static bool serialize_offset4_op (hb_serialize_context_t *c, op_code_t op, int value)
|
static bool serialize_offset4_op (hb_serialize_context_t *c, op_code_t op, int value)
|
||||||
{
|
{ return serialize_uint4_op (c, op, value); }
|
||||||
return serialize_uint4_op (c, op, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool serialize_offset2_op (hb_serialize_context_t *c, op_code_t op, int value)
|
static bool serialize_offset2_op (hb_serialize_context_t *c, op_code_t op, int value)
|
||||||
{
|
{ return serialize_uint2_op (c, op, value); }
|
||||||
return serialize_uint2_op (c, op, value);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TopDict : Dict {};
|
struct TopDict : Dict {};
|
||||||
|
@ -483,7 +479,7 @@ struct FDArray : CFFIndexOf<COUNT, FontDict>
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
|
|
||||||
/* serialize font dict offsets */
|
/* serialize font dict offsets */
|
||||||
unsigned int offset = 1;
|
unsigned int offset = 1;
|
||||||
unsigned int fid = 0;
|
unsigned int fid = 0;
|
||||||
for (; fid < fontDicts.length; fid++)
|
for (; fid < fontDicts.length; fid++)
|
||||||
{
|
{
|
||||||
|
@ -575,9 +571,7 @@ struct FDSelect0 {
|
||||||
}
|
}
|
||||||
|
|
||||||
hb_codepoint_t get_fd (hb_codepoint_t glyph) const
|
hb_codepoint_t get_fd (hb_codepoint_t glyph) const
|
||||||
{
|
{ return (hb_codepoint_t) fds[glyph]; }
|
||||||
return (hb_codepoint_t)fds[glyph];
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int get_size (unsigned int num_glyphs) const
|
unsigned int get_size (unsigned int num_glyphs) const
|
||||||
{ return HBUINT8::static_size * num_glyphs; }
|
{ return HBUINT8::static_size * num_glyphs; }
|
||||||
|
@ -588,7 +582,8 @@ struct FDSelect0 {
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename GID_TYPE, typename FD_TYPE>
|
template <typename GID_TYPE, typename FD_TYPE>
|
||||||
struct FDSelect3_4_Range {
|
struct FDSelect3_4_Range
|
||||||
|
{
|
||||||
bool sanitize (hb_sanitize_context_t *c, const void * /*nullptr*/, unsigned int fdcount) const
|
bool sanitize (hb_sanitize_context_t *c, const void * /*nullptr*/, unsigned int fdcount) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
|
@ -597,12 +592,13 @@ struct FDSelect3_4_Range {
|
||||||
|
|
||||||
GID_TYPE first;
|
GID_TYPE first;
|
||||||
FD_TYPE fd;
|
FD_TYPE fd;
|
||||||
|
public:
|
||||||
DEFINE_SIZE_STATIC (GID_TYPE::static_size + FD_TYPE::static_size);
|
DEFINE_SIZE_STATIC (GID_TYPE::static_size + FD_TYPE::static_size);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename GID_TYPE, typename FD_TYPE>
|
template <typename GID_TYPE, typename FD_TYPE>
|
||||||
struct FDSelect3_4 {
|
struct FDSelect3_4
|
||||||
|
{
|
||||||
unsigned int get_size () const
|
unsigned int get_size () const
|
||||||
{ return GID_TYPE::static_size * 2 + ranges.get_size (); }
|
{ return GID_TYPE::static_size * 2 + ranges.get_size (); }
|
||||||
|
|
||||||
|
@ -614,10 +610,8 @@ struct FDSelect3_4 {
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
|
|
||||||
for (unsigned int i = 1; i < nRanges (); i++)
|
for (unsigned int i = 1; i < nRanges (); i++)
|
||||||
{
|
|
||||||
if (unlikely (ranges[i - 1].first >= ranges[i].first))
|
if (unlikely (ranges[i - 1].first >= ranges[i].first))
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
}
|
|
||||||
|
|
||||||
if (unlikely (!sentinel().sanitize (c) || (sentinel() != c->get_num_glyphs ())))
|
if (unlikely (!sentinel().sanitize (c) || (sentinel() != c->get_num_glyphs ())))
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
|
@ -649,17 +643,8 @@ struct FDSelect3_4 {
|
||||||
typedef FDSelect3_4<HBUINT16, HBUINT8> FDSelect3;
|
typedef FDSelect3_4<HBUINT16, HBUINT8> FDSelect3;
|
||||||
typedef FDSelect3_4_Range<HBUINT16, HBUINT8> FDSelect3_Range;
|
typedef FDSelect3_4_Range<HBUINT16, HBUINT8> FDSelect3_Range;
|
||||||
|
|
||||||
struct FDSelect {
|
struct FDSelect
|
||||||
bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const
|
{
|
||||||
{
|
|
||||||
TRACE_SANITIZE (this);
|
|
||||||
|
|
||||||
return_trace (likely (c->check_struct (this) && (format == 0 || format == 3) &&
|
|
||||||
((format == 0)?
|
|
||||||
u.format0.sanitize (c, fdcount):
|
|
||||||
u.format3.sanitize (c, fdcount))));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool serialize (hb_serialize_context_t *c, const FDSelect &src, unsigned int num_glyphs)
|
bool serialize (hb_serialize_context_t *c, const FDSelect &src, unsigned int num_glyphs)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
|
@ -675,30 +660,46 @@ struct FDSelect {
|
||||||
|
|
||||||
unsigned int get_size (unsigned int num_glyphs) const
|
unsigned int get_size (unsigned int num_glyphs) const
|
||||||
{
|
{
|
||||||
unsigned int size = format.static_size;
|
switch (format)
|
||||||
if (format == 0)
|
{
|
||||||
size += u.format0.get_size (num_glyphs);
|
case 0: return format.static_size + u.format0.get_size (num_glyphs);
|
||||||
else
|
case 3: return format.static_size + u.format3.get_size ();
|
||||||
size += u.format3.get_size ();
|
default:return 0;
|
||||||
return size;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hb_codepoint_t get_fd (hb_codepoint_t glyph) const
|
hb_codepoint_t get_fd (hb_codepoint_t glyph) const
|
||||||
{
|
{
|
||||||
if (this == &Null(FDSelect))
|
if (this == &Null (FDSelect))
|
||||||
return 0;
|
return 0;
|
||||||
if (format == 0)
|
switch (format)
|
||||||
return u.format0.get_fd (glyph);
|
{
|
||||||
else
|
case 0: return u.format0.get_fd (glyph);
|
||||||
return u.format3.get_fd (glyph);
|
case 3: return u.format3.get_fd (glyph);
|
||||||
|
default:return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HBUINT8 format;
|
bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const
|
||||||
union {
|
{
|
||||||
FDSelect0 format0;
|
TRACE_SANITIZE (this);
|
||||||
FDSelect3 format3;
|
if (unlikely (!c->check_struct (this)))
|
||||||
} u;
|
return_trace (false);
|
||||||
|
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case 0: return_trace (u.format0.sanitize (c, fdcount));
|
||||||
|
case 3: return_trace (u.format3.sanitize (c, fdcount));
|
||||||
|
default:return_trace (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HBUINT8 format;
|
||||||
|
union {
|
||||||
|
FDSelect0 format0;
|
||||||
|
FDSelect3 format3;
|
||||||
|
} u;
|
||||||
|
public:
|
||||||
DEFINE_SIZE_MIN (1);
|
DEFINE_SIZE_MIN (1);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -161,21 +161,8 @@ struct CFF1SuppEncData {
|
||||||
DEFINE_SIZE_ARRAY_SIZED (1, supps);
|
DEFINE_SIZE_ARRAY_SIZED (1, supps);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Encoding {
|
struct Encoding
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
{
|
||||||
{
|
|
||||||
TRACE_SANITIZE (this);
|
|
||||||
|
|
||||||
if (unlikely (!c->check_struct (this)))
|
|
||||||
return_trace (false);
|
|
||||||
unsigned int fmt = format & 0x7F;
|
|
||||||
if (unlikely (fmt > 1))
|
|
||||||
return_trace (false);
|
|
||||||
if (unlikely (!((fmt == 0)? u.format0.sanitize (c): u.format1.sanitize (c))))
|
|
||||||
return_trace (false);
|
|
||||||
return_trace (((format & 0x80) == 0) || suppEncData ().sanitize (c));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* serialize a fullset Encoding */
|
/* serialize a fullset Encoding */
|
||||||
bool serialize (hb_serialize_context_t *c, const Encoding &src)
|
bool serialize (hb_serialize_context_t *c, const Encoding &src)
|
||||||
{
|
{
|
||||||
|
@ -197,11 +184,12 @@ struct Encoding {
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
Encoding *dest = c->extend_min (*this);
|
Encoding *dest = c->extend_min (*this);
|
||||||
if (unlikely (dest == nullptr)) return_trace (false);
|
if (unlikely (dest == nullptr)) return_trace (false);
|
||||||
dest->format = format | ((supp_codes.length > 0)? 0x80: 0);
|
dest->format = format | ((supp_codes.length > 0) ? 0x80 : 0);
|
||||||
if (format == 0)
|
switch (format) {
|
||||||
|
case 0:
|
||||||
{
|
{
|
||||||
Encoding0 *fmt0 = c->allocate_size<Encoding0> (Encoding0::min_size + HBUINT8::static_size * enc_count);
|
Encoding0 *fmt0 = c->allocate_size<Encoding0> (Encoding0::min_size + HBUINT8::static_size * enc_count);
|
||||||
if (unlikely (fmt0 == nullptr)) return_trace (false);
|
if (unlikely (fmt0 == nullptr)) return_trace (false);
|
||||||
fmt0->nCodes () = enc_count;
|
fmt0->nCodes () = enc_count;
|
||||||
unsigned int glyph = 0;
|
unsigned int glyph = 0;
|
||||||
for (unsigned int i = 0; i < code_ranges.length; i++)
|
for (unsigned int i = 0; i < code_ranges.length; i++)
|
||||||
|
@ -213,7 +201,9 @@ struct Encoding {
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
{
|
{
|
||||||
Encoding1 *fmt1 = c->allocate_size<Encoding1> (Encoding1::min_size + Encoding1_Range::static_size * code_ranges.length);
|
Encoding1 *fmt1 = c->allocate_size<Encoding1> (Encoding1::min_size + Encoding1_Range::static_size * code_ranges.length);
|
||||||
if (unlikely (fmt1 == nullptr)) return_trace (false);
|
if (unlikely (fmt1 == nullptr)) return_trace (false);
|
||||||
|
@ -226,7 +216,11 @@ struct Encoding {
|
||||||
fmt1->ranges[i].nLeft = code_ranges[i].glyph;
|
fmt1->ranges[i].nLeft = code_ranges[i].glyph;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (supp_codes.length > 0)
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (supp_codes.length)
|
||||||
{
|
{
|
||||||
CFF1SuppEncData *suppData = c->allocate_size<CFF1SuppEncData> (CFF1SuppEncData::min_size + SuppEncoding::static_size * supp_codes.length);
|
CFF1SuppEncData *suppData = c->allocate_size<CFF1SuppEncData> (CFF1SuppEncData::min_size + SuppEncoding::static_size * supp_codes.length);
|
||||||
if (unlikely (suppData == nullptr)) return_trace (false);
|
if (unlikely (suppData == nullptr)) return_trace (false);
|
||||||
|
@ -237,6 +231,7 @@ struct Encoding {
|
||||||
suppData->supps[i].glyph = supp_codes[i].glyph; /* actually SID */
|
suppData->supps[i].glyph = supp_codes[i].glyph; /* actually SID */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,11 +240,13 @@ struct Encoding {
|
||||||
unsigned int enc_count,
|
unsigned int enc_count,
|
||||||
unsigned int supp_count)
|
unsigned int supp_count)
|
||||||
{
|
{
|
||||||
unsigned int size = min_size;
|
unsigned int size = min_size;
|
||||||
if (format == 0)
|
switch (format)
|
||||||
size += Encoding0::min_size + HBUINT8::static_size * enc_count;
|
{
|
||||||
else
|
case 0: size += Encoding0::min_size + HBUINT8::static_size * enc_count; break;
|
||||||
size += Encoding1::min_size + Encoding1_Range::static_size * enc_count;
|
case 1: size += Encoding1::min_size + Encoding1_Range::static_size * enc_count; break;
|
||||||
|
default:return 0;
|
||||||
|
}
|
||||||
if (supp_count > 0)
|
if (supp_count > 0)
|
||||||
size += CFF1SuppEncData::min_size + SuppEncoding::static_size * supp_count;
|
size += CFF1SuppEncData::min_size + SuppEncoding::static_size * supp_count;
|
||||||
return size;
|
return size;
|
||||||
|
@ -258,10 +255,11 @@ struct Encoding {
|
||||||
unsigned int get_size () const
|
unsigned int get_size () const
|
||||||
{
|
{
|
||||||
unsigned int size = min_size;
|
unsigned int size = min_size;
|
||||||
if (table_format () == 0)
|
switch (table_format ())
|
||||||
size += u.format0.get_size ();
|
{
|
||||||
else
|
case 0: size += u.format0.get_size (); break;
|
||||||
size += u.format1.get_size ();
|
case 1: size += u.format1.get_size (); break;
|
||||||
|
}
|
||||||
if (has_supplement ())
|
if (has_supplement ())
|
||||||
size += suppEncData ().get_size ();
|
size += suppEncData ().get_size ();
|
||||||
return size;
|
return size;
|
||||||
|
@ -269,14 +267,16 @@ struct Encoding {
|
||||||
|
|
||||||
hb_codepoint_t get_code (hb_codepoint_t glyph) const
|
hb_codepoint_t get_code (hb_codepoint_t glyph) const
|
||||||
{
|
{
|
||||||
if (table_format () == 0)
|
switch (table_format ())
|
||||||
return u.format0.get_code (glyph);
|
{
|
||||||
else
|
case 0: return u.format0.get_code (glyph);
|
||||||
return u.format1.get_code (glyph);
|
case 1: return u.format1.get_code (glyph);
|
||||||
|
default:return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t table_format () const { return (format & 0x7F); }
|
uint8_t table_format () const { return format & 0x7F; }
|
||||||
bool has_supplement () const { return (format & 0x80) != 0; }
|
bool has_supplement () const { return format & 0x80; }
|
||||||
|
|
||||||
void get_supplement_codes (hb_codepoint_t sid, hb_vector_t<hb_codepoint_t> &codes) const
|
void get_supplement_codes (hb_codepoint_t sid, hb_vector_t<hb_codepoint_t> &codes) const
|
||||||
{
|
{
|
||||||
|
@ -285,21 +285,37 @@ struct Encoding {
|
||||||
suppEncData().get_codes (sid, codes);
|
suppEncData().get_codes (sid, codes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SANITIZE (this);
|
||||||
|
if (unlikely (!c->check_struct (this)))
|
||||||
|
return_trace (false);
|
||||||
|
|
||||||
|
switch (table_format ())
|
||||||
|
{
|
||||||
|
case 0: if (unlikely (!u.format0.sanitize (c))) { return_trace (false); } break;
|
||||||
|
case 1: if (unlikely (!u.format1.sanitize (c))) { return_trace (false); } break;
|
||||||
|
default:return_trace (false);
|
||||||
|
}
|
||||||
|
return_trace (likely (!has_supplement () || suppEncData ().sanitize (c)));
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const CFF1SuppEncData &suppEncData () const
|
const CFF1SuppEncData &suppEncData () const
|
||||||
{
|
{
|
||||||
if ((format & 0x7F) == 0)
|
switch (table_format ())
|
||||||
return StructAfter<CFF1SuppEncData> (u.format0.codes[u.format0.nCodes ()-1]);
|
{
|
||||||
else
|
case 0: return StructAfter<CFF1SuppEncData> (u.format0.codes[u.format0.nCodes ()-1]);
|
||||||
return StructAfter<CFF1SuppEncData> (u.format1.ranges[u.format1.nRanges ()-1]);
|
case 1: return StructAfter<CFF1SuppEncData> (u.format1.ranges[u.format1.nRanges ()-1]);
|
||||||
|
default:return Null (CFF1SuppEncData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HBUINT8 format;
|
HBUINT8 format;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
Encoding0 format0;
|
Encoding0 format0;
|
||||||
Encoding1 format1;
|
Encoding1 format1;
|
||||||
} u;
|
} u;
|
||||||
/* CFF1SuppEncData suppEncData; */
|
/* CFF1SuppEncData suppEncData; */
|
||||||
|
|
||||||
|
@ -433,23 +449,8 @@ typedef Charset1_2<HBUINT16> Charset2;
|
||||||
typedef Charset_Range<HBUINT8> Charset1_Range;
|
typedef Charset_Range<HBUINT8> Charset1_Range;
|
||||||
typedef Charset_Range<HBUINT16> Charset2_Range;
|
typedef Charset_Range<HBUINT16> Charset2_Range;
|
||||||
|
|
||||||
struct Charset {
|
struct Charset
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
{
|
||||||
{
|
|
||||||
TRACE_SANITIZE (this);
|
|
||||||
|
|
||||||
if (unlikely (!c->check_struct (this)))
|
|
||||||
return_trace (false);
|
|
||||||
if (format == 0)
|
|
||||||
return_trace (u.format0.sanitize (c, c->get_num_glyphs ()));
|
|
||||||
else if (format == 1)
|
|
||||||
return_trace (u.format1.sanitize (c, c->get_num_glyphs ()));
|
|
||||||
else if (likely (format == 2))
|
|
||||||
return_trace (u.format2.sanitize (c, c->get_num_glyphs ()));
|
|
||||||
else
|
|
||||||
return_trace (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* serialize a fullset Charset */
|
/* serialize a fullset Charset */
|
||||||
bool serialize (hb_serialize_context_t *c, const Charset &src, unsigned int num_glyphs)
|
bool serialize (hb_serialize_context_t *c, const Charset &src, unsigned int num_glyphs)
|
||||||
{
|
{
|
||||||
|
@ -471,10 +472,12 @@ struct Charset {
|
||||||
Charset *dest = c->extend_min (*this);
|
Charset *dest = c->extend_min (*this);
|
||||||
if (unlikely (dest == nullptr)) return_trace (false);
|
if (unlikely (dest == nullptr)) return_trace (false);
|
||||||
dest->format = format;
|
dest->format = format;
|
||||||
if (format == 0)
|
switch (format)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
{
|
{
|
||||||
Charset0 *fmt0 = c->allocate_size<Charset0> (Charset0::min_size + HBUINT16::static_size * (num_glyphs - 1));
|
Charset0 *fmt0 = c->allocate_size<Charset0> (Charset0::min_size + HBUINT16::static_size * (num_glyphs - 1));
|
||||||
if (unlikely (fmt0 == nullptr)) return_trace (false);
|
if (unlikely (fmt0 == nullptr)) return_trace (false);
|
||||||
unsigned int glyph = 0;
|
unsigned int glyph = 0;
|
||||||
for (unsigned int i = 0; i < sid_ranges.length; i++)
|
for (unsigned int i = 0; i < sid_ranges.length; i++)
|
||||||
{
|
{
|
||||||
|
@ -483,7 +486,9 @@ struct Charset {
|
||||||
fmt0->sids[glyph++] = sid++;
|
fmt0->sids[glyph++] = sid++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (format == 1)
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
{
|
{
|
||||||
Charset1 *fmt1 = c->allocate_size<Charset1> (Charset1::min_size + Charset1_Range::static_size * sid_ranges.length);
|
Charset1 *fmt1 = c->allocate_size<Charset1> (Charset1::min_size + Charset1_Range::static_size * sid_ranges.length);
|
||||||
if (unlikely (fmt1 == nullptr)) return_trace (false);
|
if (unlikely (fmt1 == nullptr)) return_trace (false);
|
||||||
|
@ -495,7 +500,9 @@ struct Charset {
|
||||||
fmt1->ranges[i].nLeft = sid_ranges[i].glyph;
|
fmt1->ranges[i].nLeft = sid_ranges[i].glyph;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else /* format 2 */
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
{
|
{
|
||||||
Charset2 *fmt2 = c->allocate_size<Charset2> (Charset2::min_size + Charset2_Range::static_size * sid_ranges.length);
|
Charset2 *fmt2 = c->allocate_size<Charset2> (Charset2::min_size + Charset2_Range::static_size * sid_ranges.length);
|
||||||
if (unlikely (fmt2 == nullptr)) return_trace (false);
|
if (unlikely (fmt2 == nullptr)) return_trace (false);
|
||||||
|
@ -506,56 +513,72 @@ struct Charset {
|
||||||
fmt2->ranges[i].first = sid_ranges[i].code;
|
fmt2->ranges[i].first = sid_ranges[i].code;
|
||||||
fmt2->ranges[i].nLeft = sid_ranges[i].glyph;
|
fmt2->ranges[i].nLeft = sid_ranges[i].glyph;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parallel to above: calculate the size of a subset Charset */
|
/* parallel to above: calculate the size of a subset Charset */
|
||||||
static unsigned int calculate_serialized_size (
|
static unsigned int calculate_serialized_size (uint8_t format,
|
||||||
uint8_t format,
|
unsigned int count)
|
||||||
unsigned int count)
|
|
||||||
{
|
{
|
||||||
unsigned int size = min_size;
|
switch (format)
|
||||||
if (format == 0)
|
{
|
||||||
size += Charset0::min_size + HBUINT16::static_size * (count - 1);
|
case 0: return min_size + Charset0::min_size + HBUINT16::static_size * (count - 1);
|
||||||
else if (format == 1)
|
case 1: return min_size + Charset1::min_size + Charset1_Range::static_size * count;
|
||||||
size += Charset1::min_size + Charset1_Range::static_size * count;
|
case 2: return min_size + Charset2::min_size + Charset2_Range::static_size * count;
|
||||||
else
|
default:return 0;
|
||||||
size += Charset2::min_size + Charset2_Range::static_size * count;
|
}
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int get_size (unsigned int num_glyphs) const
|
unsigned int get_size (unsigned int num_glyphs) const
|
||||||
{
|
{
|
||||||
unsigned int size = min_size;
|
switch (format)
|
||||||
if (format == 0)
|
{
|
||||||
size += u.format0.get_size (num_glyphs);
|
case 0: return min_size + u.format0.get_size (num_glyphs);
|
||||||
else if (format == 1)
|
case 1: return min_size + u.format1.get_size (num_glyphs);
|
||||||
size += u.format1.get_size (num_glyphs);
|
case 2: return min_size + u.format2.get_size (num_glyphs);
|
||||||
else
|
default:return 0;
|
||||||
size += u.format2.get_size (num_glyphs);
|
}
|
||||||
return size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hb_codepoint_t get_sid (hb_codepoint_t glyph) const
|
hb_codepoint_t get_sid (hb_codepoint_t glyph) const
|
||||||
{
|
{
|
||||||
if (format == 0)
|
switch (format)
|
||||||
return u.format0.get_sid (glyph);
|
{
|
||||||
else if (format == 1)
|
case 0: return u.format0.get_sid (glyph);
|
||||||
return u.format1.get_sid (glyph);
|
case 1: return u.format1.get_sid (glyph);
|
||||||
else
|
case 2: return u.format2.get_sid (glyph);
|
||||||
return u.format2.get_sid (glyph);
|
default:return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hb_codepoint_t get_glyph (hb_codepoint_t sid, unsigned int num_glyphs) const
|
hb_codepoint_t get_glyph (hb_codepoint_t sid, unsigned int num_glyphs) const
|
||||||
{
|
{
|
||||||
if (format == 0)
|
switch (format)
|
||||||
return u.format0.get_glyph (sid, num_glyphs);
|
{
|
||||||
else if (format == 1)
|
case 0: return u.format0.get_glyph (sid, num_glyphs);
|
||||||
return u.format1.get_glyph (sid, num_glyphs);
|
case 1: return u.format1.get_glyph (sid, num_glyphs);
|
||||||
else
|
case 2: return u.format2.get_glyph (sid, num_glyphs);
|
||||||
return u.format2.get_glyph (sid, num_glyphs);
|
default:return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SANITIZE (this);
|
||||||
|
if (unlikely (!c->check_struct (this)))
|
||||||
|
return_trace (false);
|
||||||
|
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case 0: return_trace (u.format0.sanitize (c, c->get_num_glyphs ()));
|
||||||
|
case 1: return_trace (u.format1.sanitize (c, c->get_num_glyphs ()));
|
||||||
|
case 2: return_trace (u.format2.sanitize (c, c->get_num_glyphs ()));
|
||||||
|
default:return_trace (false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HBUINT8 format;
|
HBUINT8 format;
|
||||||
|
|
|
@ -51,18 +51,6 @@ typedef FDSelect3_4_Range<HBUINT32, HBUINT16> FDSelect4_Range;
|
||||||
|
|
||||||
struct CFF2FDSelect
|
struct CFF2FDSelect
|
||||||
{
|
{
|
||||||
bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const
|
|
||||||
{
|
|
||||||
TRACE_SANITIZE (this);
|
|
||||||
|
|
||||||
return_trace (likely (c->check_struct (this) && (format == 0 || format == 3 || format == 4) &&
|
|
||||||
((format == 0)?
|
|
||||||
u.format0.sanitize (c, fdcount):
|
|
||||||
((format == 3)?
|
|
||||||
u.format3.sanitize (c, fdcount):
|
|
||||||
u.format4.sanitize (c, fdcount)))));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool serialize (hb_serialize_context_t *c, const CFF2FDSelect &src, unsigned int num_glyphs)
|
bool serialize (hb_serialize_context_t *c, const CFF2FDSelect &src, unsigned int num_glyphs)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
|
@ -78,35 +66,51 @@ struct CFF2FDSelect
|
||||||
|
|
||||||
unsigned int get_size (unsigned int num_glyphs) const
|
unsigned int get_size (unsigned int num_glyphs) const
|
||||||
{
|
{
|
||||||
unsigned int size = format.static_size;
|
switch (format)
|
||||||
if (format == 0)
|
{
|
||||||
size += u.format0.get_size (num_glyphs);
|
case 0: return format.static_size + u.format0.get_size (num_glyphs);
|
||||||
else if (format == 3)
|
case 3: return format.static_size + u.format3.get_size ();
|
||||||
size += u.format3.get_size ();
|
case 4: return format.static_size + u.format4.get_size ();
|
||||||
else
|
default:return 0;
|
||||||
size += u.format4.get_size ();
|
}
|
||||||
return size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hb_codepoint_t get_fd (hb_codepoint_t glyph) const
|
hb_codepoint_t get_fd (hb_codepoint_t glyph) const
|
||||||
{
|
{
|
||||||
if (this == &Null(CFF2FDSelect))
|
if (this == &Null (CFF2FDSelect))
|
||||||
return 0;
|
return 0;
|
||||||
if (format == 0)
|
|
||||||
return u.format0.get_fd (glyph);
|
switch (format)
|
||||||
else if (format == 3)
|
{
|
||||||
return u.format3.get_fd (glyph);
|
case 0: return u.format0.get_fd (glyph);
|
||||||
else
|
case 3: return u.format3.get_fd (glyph);
|
||||||
return u.format4.get_fd (glyph);
|
case 4: return u.format4.get_fd (glyph);
|
||||||
|
default:return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HBUINT8 format;
|
bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const
|
||||||
union {
|
{
|
||||||
FDSelect0 format0;
|
TRACE_SANITIZE (this);
|
||||||
FDSelect3 format3;
|
if (unlikely (!c->check_struct (this)))
|
||||||
FDSelect4 format4;
|
return_trace (false);
|
||||||
} u;
|
|
||||||
|
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case 0: return_trace (u.format0.sanitize (c, fdcount));
|
||||||
|
case 3: return_trace (u.format3.sanitize (c, fdcount));
|
||||||
|
case 4: return_trace (u.format4.sanitize (c, fdcount));
|
||||||
|
default:return_trace (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HBUINT8 format;
|
||||||
|
union {
|
||||||
|
FDSelect0 format0;
|
||||||
|
FDSelect3 format3;
|
||||||
|
FDSelect4 format4;
|
||||||
|
} u;
|
||||||
|
public:
|
||||||
DEFINE_SIZE_MIN (2);
|
DEFINE_SIZE_MIN (2);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1040,7 +1040,7 @@ static inline bool _write_cff1 (const cff_subset_plan &plan,
|
||||||
bool result;
|
bool result;
|
||||||
cff_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints);
|
cff_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints);
|
||||||
/* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */
|
/* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */
|
||||||
unsigned int subroffset = (plan.offsets.localSubrsInfos[i].size > 0)? priv_size: 0;
|
unsigned int subroffset = (plan.offsets.localSubrsInfos[i].size > 0) ? priv_size : 0;
|
||||||
result = pd->serialize (&c, acc.privateDicts[i], privSzr, subroffset);
|
result = pd->serialize (&c, acc.privateDicts[i], privSzr, subroffset);
|
||||||
if (unlikely (!result))
|
if (unlikely (!result))
|
||||||
{
|
{
|
||||||
|
|
|
@ -547,7 +547,7 @@ static inline bool _write_cff2 (const cff2_subset_plan &plan,
|
||||||
bool result;
|
bool result;
|
||||||
cff_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints);
|
cff_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints);
|
||||||
/* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */
|
/* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */
|
||||||
unsigned int subroffset = (plan.offsets.localSubrsInfos[i].size > 0)? priv_size: 0;
|
unsigned int subroffset = (plan.offsets.localSubrsInfos[i].size > 0) ? priv_size : 0;
|
||||||
result = pd->serialize (&c, acc.privateDicts[i], privSzr, subroffset);
|
result = pd->serialize (&c, acc.privateDicts[i], privSzr, subroffset);
|
||||||
if (unlikely (!result))
|
if (unlikely (!result))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue