return_trace (true);
}
-
+
inline static bool serialize_int4 (hb_serialize_context_t *c, int value)
{ return serialize_int<HBUINT32, 0, 0x7FFFFFFF> (c, OpCode_longintdict, value); }
-
+
inline static bool serialize_int2 (hb_serialize_context_t *c, int value)
{ return serialize_int<HBUINT16, 0, 0x7FFF> (c, OpCode_shortint, value); }
inline unsigned int pop_uint (void)
{
-
int i = pop_int ();
if (unlikely (i < 0))
{
env.argStack.push_int ((int16_t)((op - OpCode_TwoBytePosInt0) * 256 + env.substr[0] + 108));
env.substr.inc ();
break;
-
+
case OpCode_TwoByteNegInt0: case OpCode_TwoByteNegInt1:
case OpCode_TwoByteNegInt2: case OpCode_TwoByteNegInt3:
env.argStack.push_int ((int16_t)(-(op - OpCode_TwoByteNegInt0) * 256 - env.substr[0] - 108));
struct CSOpSet : OpSet<ARG>
{
static inline void process_op (OpCode op, ENV &env, PARAM& param)
- {
+ {
switch (op) {
case OpCode_return:
PATH::line (env, param, pt1);
}
}
-
+
static inline void hlineto (ENV &env, PARAM& param)
{
Point pt1;
if (SUPER::env.is_endchar ())
break;
}
-
+
return true;
}
case EXP_NEG:
exp_neg = true;
HB_FALLTHROUGH;
-
+
case EXP_POS:
if (part == EXP_PART)
{
case INT_PART:
int_part = (int_part * 10) + d;
break;
-
+
case FRAC_PART:
frac_part = (frac_part * 10) + d;
frac_count++;
if (unlikely (SUPER::env.in_error ()))
return false;
}
-
+
return true;
}
const int *coords_=nullptr, unsigned int num_coords_=0)
{
SUPER::init (str, *acc.globalSubrs, *acc.privateDicts[fd].localSubrs);
-
+
coords = coords_;
num_coords = num_coords_;
varStore = acc.varStore;
this->offSize.set (offSize_);
if (!unlikely (c->allocate_size<HBUINT8> (offSize_ * (byteArray.len + 1))))
return_trace (false);
-
+
/* serialize indices */
unsigned int offset = 1;
unsigned int i = 0;
this->offSize.set (offSize_);
if (!unlikely (c->allocate_size<HBUINT8> (offSize_ * (dataArrayLen + 1))))
return_trace (false);
-
+
/* serialize indices */
unsigned int offset = 1;
unsigned int i = 0;
this->offSize.set (offSize_);
if (!unlikely (c->allocate_size<HBUINT8> (offSize_ * (fontDicts.len + 1))))
return_trace (false);
-
+
/* serialize font dict offsets */
unsigned int offset = 1;
unsigned int fid = 0;
}
return_trace (true);
}
-
+
/* used by CFF2 */
template <typename DICTVAL, typename OP_SERIALIZER>
inline bool serialize (hb_serialize_context_t *c,
this->offSize.set (offSize_);
if (!unlikely (c->allocate_size<HBUINT8> (offSize_ * (fdCount + 1))))
return_trace (false);
-
+
/* serialize font dict offsets */
unsigned int offset = 1;
unsigned int fid = 0;
}
return_trace (true);
}
-
+
/* in parallel to above */
template <typename OP_SERIALIZER, typename DICTVAL>
inline static unsigned int calculate_serialized_size (unsigned int &offSize_ /* OUT */,
return (hb_codepoint_t)ranges[i].first + glyph;
glyph -= (ranges[i].nLeft + 1);
}
-
+
return 0;
}
return glyph + (sid - ranges[i].first);
glyph += (ranges[i].nLeft + 1);
}
-
+
return 0;
}
{
unsigned int size = HBUINT8::static_size;
int glyph = (int)num_glyphs;
-
+
assert (glyph > 0);
glyph--;
for (unsigned int i = 0; glyph > 0; i++)
count.set (0);
return_trace (true);
}
-
+
ByteStrArray bytesArray;
bytesArray.init ();
if (!bytesArray.resize (sidmap.get_count ()))
bytesArray.fini ();
return_trace (result);
}
-
+
/* in parallel to above */
inline unsigned int calculate_serialized_size (unsigned int &offSize /*OUT*/, const Remap &sidmap) const
{
case OpCode_BaseFontBlend:
env.clear_args ();
break;
-
+
case OpCode_CIDCount:
dictval.cidCount = env.argStack.pop_uint ();
env.clear_args ();
dictval.FDSelectOffset = env.argStack.pop_uint ();
env.clear_args ();
break;
-
+
case OpCode_Private:
dictval.privateDictInfo.offset = env.argStack.pop_uint ();
dictval.privateDictInfo.size = env.argStack.pop_uint ();
env.clear_args ();
break;
-
+
default:
env.last_offset = env.substr.offset;
TopDictOpSet<CFF1TopDictVal>::process_op (op, env, dictval);
dictval.privateDictInfo.size = env.argStack.pop_uint ();
env.clear_args ();
break;
-
+
default:
DictOpSet::process_op (op, env);
if (!env.argStack.is_empty ()) return;
topDict.init ();
fontDicts.init ();
privateDicts.init ();
-
+
this->blob = sc.reference_table<cff1> (face);
/* setup for run-time santization */
sc.init (this->blob);
sc.start_processing ();
-
+
const OT::cff1 *cff = this->blob->template as<OT::cff1> ();
if (cff == &Null(OT::cff1))
topDict.init ();
if (unlikely (!top_interp.interpret (topDict))) { fini (); return; }
}
-
+
if (is_predef_charset ())
charset = &Null(Charset);
else
{
CFF1TopDictValues *font = &topDict;
PRIVDICTVAL *priv = &privateDicts[0];
-
+
const ByteStr privDictStr (StructAtOffset<UnsizedByteStr> (cff, font->privateDictInfo.offset), font->privateDictInfo.size);
if (unlikely (!privDictStr.sanitize (&sc))) { fini (); return; }
DictInterpreter<PRIVOPSET, PRIVDICTVAL> priv_interp;
hb_codepoint_t sid = lookup_standard_encoding_for_sid (code);
if (unlikely (sid == CFF_UNDEF_SID))
return 0;
-
+
if (charset != &Null(Charset))
return charset->get_glyph (sid, num_glyphs);
else if ((topDict.CharsetOffset == ISOAdobeCharset)
{
SUPER::init (face);
if (blob == nullptr) return;
-
+
const OT::cff1 *cff = this->blob->as<OT::cff1> ();
encoding = &Null(Encoding);
if (is_CID ())
dictval.FDSelectOffset = env.argStack.pop_uint ();
env.clear_args ();
break;
-
+
default:
SUPER::process_op (op, env, dictval);
/* Record this operand below if stack is empty, otherwise done */
dictval.privateDictInfo.size = env.argStack.pop_uint ();
env.clear_args ();
break;
-
+
default:
SUPER::process_op (op, env);
if (!env.argStack.is_empty ())
topDict.init ();
fontDicts.init ();
privateDicts.init ();
-
+
this->blob = sc.reference_table<cff2> (face);
/* setup for run-time santization */
sc.init (this->blob);
sc.start_processing ();
-
+
const OT::cff2 *cff2 = this->blob->template as<OT::cff2> ();
if (cff2 == &Null(OT::cff2))
topDict.init ();
if (unlikely (!top_interp.interpret (topDict))) { fini (); return; }
}
-
+
globalSubrs = &StructAtOffset<CFF2Subrs> (cff2, cff2->topDict + cff2->topDictSize);
varStore = &StructAtOffsetOrNull<CFF2VariationStore> (cff2, topDict.vstoreOffset);
charStrings = &StructAtOffsetOrNull<CFF2CharStrings> (cff2, topDict.charStringsOffset);
fdArray = &StructAtOffsetOrNull<CFF2FDArray> (cff2, topDict.FDArrayOffset);
fdSelect = &StructAtOffsetOrNull<CFF2FDSelect> (cff2, topDict.FDSelectOffset);
-
+
if (((varStore != &Null(CFF2VariationStore)) && unlikely (!varStore->sanitize (&sc))) ||
(charStrings == &Null(CFF2CharStrings)) || unlikely (!charStrings->sanitize (&sc)) ||
(fdArray == &Null(CFF2FDArray)) || unlikely (!fdArray->sanitize (&sc)) ||
{
hb_codepoint_t fd = src.get_fd (glyphs[i]);
set->add (fd);
-
+
if (fd != prev_fd)
{
num_ranges++;
break;
}
#endif /* CFF_SERIALIZE_FDSELECT_0 */
-
+
case 3:
return serialize_fdselect_3_4<FDSelect3> (c,
num_glyphs,
src,
size,
fdselect_ranges);
-
+
case 4:
return serialize_fdselect_3_4<FDSelect4> (c,
num_glyphs,
default:
assert(false);
}
-
+
return_trace (true);
}
protected:
inline void set_error (void) { error = true; }
-
+
StrBuff &buff;
bool error;
};
struct CFFSubTableOffsets {
inline CFFSubTableOffsets (void)
: privateDictsOffset (0)
-
+
{
topDictInfo.init ();
FDSelectInfo.init ();
}
return true;
}
-
+
const ACC &acc;
const hb_vector_t<hb_codepoint_t> &glyphs;
bool drop_hints;
unsigned int parsed_len = get_count ();
if (likely (parsed_len > 0))
values[parsed_len-1].set_skip ();
-
+
ParsedCSOp val;
val.init (subr_num);
SUPER::add_op (op, substr, val);
{
case CSType_CharString:
return parsed_charstring;
-
+
case CSType_LocalSubr:
if (likely (context.subr_num < parsed_local_subrs->len))
return &(*parsed_local_subrs)[context.subr_num];
break;
-
+
case CSType_GlobalSubr:
if (likely (context.subr_num < parsed_global_subrs->len))
return &(*parsed_global_subrs)[context.subr_num];
if (hb_set_has (closure, old_num))
add (old_num);
}
-
+
if (get_count () < 1240)
bias = 107;
else if (get_count () < 33900)
hb_codepoint_t glyph = glyphs[i];
const ByteStr str = (*acc.charStrings)[glyph];
unsigned int fd = acc.fdSelect->get_fd (glyph);
-
+
CSInterpreter<ENV, OPSET, SubrSubsetParam> interp;
interp.env.init (str, acc, fd);
/* finalize parsed string esp. copy CFF1 width or CFF2 vsindex to the parsed charstring for encoding */
SUBSETTER::finalize_parsed_str (interp.env, param, parsed_charstrings[i]);
}
-
+
if (drop_hints)
{
/* mark hint ops and arguments for drop */
collect_subr_refs_in_str (parsed_charstrings[i], param);
}
}
-
+
remaps.create (closures);
-
+
return true;
}
inline bool encode_subrs (const ParsedCStrs &subrs, const SubrRemap& remap, unsigned int fd, StrBuffArray &buffArray) const
{
unsigned int count = remap.get_count ();
-
+
if (unlikely (!buffArray.resize (count)))
return false;
for (unsigned int old_num = 0; old_num < subrs.len; old_num++)
: seen_moveto (false),
ends_in_hint (false),
vsindex_dropped (false) {}
-
+
bool seen_moveto;
bool ends_in_hint;
bool vsindex_dropped;
};
-
+
inline bool drop_hints_in_subr (ParsedCStr &str, unsigned int pos,
ParsedCStrs &subrs, unsigned int subr_num,
const SubrSubsetParam ¶m, DropHintsParam &drop)
if (!str.at_end (pos))
drop.ends_in_hint = false;
}
-
+
return has_hint;
}
has_hint = drop_hints_in_subr (str, pos,
*param.parsed_local_subrs, str.values[pos].subr_num,
param, drop);
-
+
break;
case OpCode_callgsubr:
encoder.encode_int (remaps.local_remaps[fd].biased_num (opstr.subr_num));
encoder.encode_op (OpCode_callsubr);
break;
-
+
case OpCode_callgsubr:
encoder.encode_int (remaps.global_remap.biased_num (opstr.subr_num));
encoder.encode_op (OpCode_callgsubr);
case OpCode_charset:
case OpCode_Encoding:
return OpCode_Size (OpCode_longintdict) + 4 + OpCode_Size (op);
-
+
case OpCode_Private:
return OpCode_Size (OpCode_longintdict) + 4 + OpCode_Size (OpCode_shortint) + 2 + OpCode_Size (OpCode_Private);
-
+
case OpCode_version:
case OpCode_Notice:
case OpCode_Copyright:
return;
}
HB_FALLTHROUGH;
-
+
default:
SUPER::flush_args_and_op (op, env, param);
break;
{
if (unlikely (!sidmap.reset (acc.stringIndex->count)))
return false;
-
+
for (unsigned int i = 0; i < NameDictValues::ValCount; i++)
{
unsigned int sid = acc.topDict.nameSIDs[i];
for (unsigned int i = 0; i < orig_fdcount; i++)
if (fdmap.includes (i))
(void)sidmap.add (acc.fontDicts[i].fontName);
-
+
return true;
}
/* CFF header */
final_size += OT::cff1::static_size;
-
+
/* Name INDEX */
offsets.nameIndexOffset = final_size;
final_size += acc.nameIndex->get_size ();
offsets.stringIndexInfo.size = acc.stringIndex->calculate_serialized_size (offsets.stringIndexInfo.offSize, sidmap);
final_size += offsets.stringIndexInfo.size;
}
-
+
if (desubroutinize)
{
/* Flatten global & local subrs */
flattener(acc, plan->glyphs, plan->drop_hints);
if (!flattener.flatten (subset_charstrings))
return false;
-
+
/* no global/local subroutines */
offsets.globalSubrsInfo.size = CFF1Subrs::calculate_serialized_size (1, 0, 0);
}
{
assert (plan.offsets.globalSubrsInfo.offset != 0);
assert (plan.offsets.globalSubrsInfo.offset == c.head - c.start);
-
+
CFF1Subrs *dest = c.start_embed <CFF1Subrs> ();
if (unlikely (dest == nullptr)) return false;
if (unlikely (!dest->serialize (&c, plan.offsets.globalSubrsInfo.offSize, plan.subset_globalsubrs)))
if (acc.fdSelect != &Null(CFF1FDSelect))
{
assert (plan.offsets.FDSelectInfo.offset == c.head - c.start);
-
+
if (unlikely (!hb_serialize_cff_fdselect (&c, glyphs.len, *acc.fdSelect, acc.fdCount,
plan.subset_fdselect_format, plan.offsets.FDSelectInfo.size,
plan.subset_fdselect_ranges)))
{
case OpCode_vstore:
return OpCode_Size (OpCode_longintdict) + 4 + OpCode_Size (opstr.op);
-
+
default:
return CFFTopDict_OpSerializer<>::calculate_serialized_size (opstr);
}
case OpCode_endchar:
/* dummy opcodes in CFF2. ignore */
break;
-
+
case OpCode_hstem:
case OpCode_hstemhm:
case OpCode_vstem:
return;
}
HB_FALLTHROUGH;
-
+
default:
SUPER::flush_args_and_op (op, env, param);
break;
encoder.encode_int (arg.numValues);
encoder.encode_op (OpCode_blendcs);
}
-
+
static inline void flush_op (OpCode op, CFF2CSInterpEnv &env, FlattenParam& param)
{
switch (op)
/* CFF2 header */
final_size += OT::cff2::static_size;
-
+
/* top dict */
{
CFF2TopDict_OpSerializer topSzr;
flattener(acc, plan->glyphs, plan->drop_hints);
if (!flattener.flatten (subset_charstrings))
return false;
-
+
/* no global/local subroutines */
offsets.globalSubrsInfo.size = CFF2Subrs::calculate_serialized_size (1, 0, 0);
}
subset_fdselect_ranges,
fdmap)))
return false;
-
+
final_size += offsets.FDSelectInfo.size;
}
else
return false;
}
}
-
+
/* variation store */
if (acc.varStore != &Null(CFF2VariationStore))
{
if (acc.fdSelect != &Null(CFF2FDSelect))
{
assert (plan.offsets.FDSelectInfo.offset == c.head - c.start);
-
+
if (unlikely (!hb_serialize_cff_fdselect (&c, glyphs.len, *(const FDSelect *)acc.fdSelect, acc.fdArray->count,
plan.subset_fdselect_format, plan.offsets.FDSelectInfo.size,
plan.subset_fdselect_ranges)))