CFF2 subroutine flattner
Factored out CFF1 & CFF2 common subsetting code in hb-subset-cff-common.hh
diff --git a/src/hb-subset-cff-common.hh b/src/hb-subset-cff-common.hh
index 4ed8248..f7294cc 100644
--- a/src/hb-subset-cff-common.hh
+++ b/src/hb-subset-cff-common.hh
@@ -98,6 +98,160 @@
}
};
+struct CFFSubTableOffsets {
+ inline CFFSubTableOffsets (void)
+ : privateDictsOffset (0)
+
+ {
+ topDictInfo.init ();
+ FDSelectInfo.init ();
+ FDArrayInfo.init ();
+ charStringsInfo.init ();
+ globalSubrsInfo.init ();
+ localSubrsInfos.init ();
+ }
+
+ inline ~CFFSubTableOffsets (void)
+ {
+ localSubrsInfos.fini ();
+ }
+
+ TableInfo topDictInfo;
+ TableInfo FDSelectInfo;
+ TableInfo FDArrayInfo;
+ TableInfo charStringsInfo;
+ unsigned int privateDictsOffset;
+ TableInfo globalSubrsInfo;
+ hb_vector_t<TableInfo> localSubrsInfos;
+};
+
+struct CFFTopDict_OpSerializer : OpSerializer
+{
+ inline bool serialize (hb_serialize_context_t *c,
+ const OpStr &opstr,
+ const CFFSubTableOffsets &offsets) const
+ {
+ TRACE_SERIALIZE (this);
+
+ switch (opstr.op)
+ {
+ case OpCode_CharStrings:
+ return_trace (FontDict::serialize_offset4_op(c, opstr.op, offsets.charStringsInfo.offset));
+
+ case OpCode_FDArray:
+ return_trace (FontDict::serialize_offset4_op(c, opstr.op, offsets.FDArrayInfo.offset));
+
+ case OpCode_FDSelect:
+ return_trace (FontDict::serialize_offset4_op(c, opstr.op, offsets.FDSelectInfo.offset));
+
+ default:
+ return_trace (copy_opstr (c, opstr));
+ }
+ return_trace (true);
+ }
+
+ inline unsigned int calculate_serialized_size (const OpStr &opstr) const
+ {
+ switch (opstr.op)
+ {
+ case OpCode_CharStrings:
+ case OpCode_FDArray:
+ case OpCode_FDSelect:
+ return OpCode_Size (OpCode_longintdict) + 4 + OpCode_Size (opstr.op);
+
+ default:
+ return opstr.str.len;
+ }
+ }
+};
+
+struct CFFFontDict_OpSerializer : OpSerializer
+{
+ inline bool serialize (hb_serialize_context_t *c,
+ const OpStr &opstr,
+ const TableInfo &privateDictInfo) const
+ {
+ TRACE_SERIALIZE (this);
+
+ if (opstr.op == OpCode_Private)
+ {
+ /* serialize the private dict size as a 2-byte integer */
+ if (unlikely (!UnsizedByteStr::serialize_int2 (c, privateDictInfo.size)))
+ return_trace (false);
+
+ /* serialize the private dict offset as a 4-byte integer */
+ if (unlikely (!UnsizedByteStr::serialize_int4 (c, privateDictInfo.offset)))
+ return_trace (false);
+
+ /* serialize the opcode */
+ HBUINT8 *p = c->allocate_size<HBUINT8> (1);
+ if (unlikely (p == nullptr)) return_trace (false);
+ p->set (OpCode_Private);
+
+ return_trace (true);
+ }
+ else
+ {
+ HBUINT8 *d = c->allocate_size<HBUINT8> (opstr.str.len);
+ if (unlikely (d == nullptr)) return_trace (false);
+ memcpy (d, &opstr.str.str[0], opstr.str.len);
+ }
+ return_trace (true);
+ }
+
+ inline unsigned int calculate_serialized_size (const OpStr &opstr) const
+ {
+ if (opstr.op == OpCode_Private)
+ return OpCode_Size (OpCode_longintdict) + 4 + OpCode_Size (OpCode_shortint) + 2 + OpCode_Size (OpCode_Private);
+ else
+ return opstr.str.len;
+ }
+};
+
+struct CFFPrivateDict_OpSerializer : OpSerializer
+{
+ inline CFFPrivateDict_OpSerializer (bool drop_hints_=false, bool flatten_subrs_=false)
+ : drop_hints (drop_hints_), flatten_subrs (flatten_subrs_) {}
+
+ inline bool serialize (hb_serialize_context_t *c,
+ const OpStr &opstr,
+ const unsigned int subrsOffset) const
+ {
+ TRACE_SERIALIZE (this);
+
+ if (drop_hints && DictOpSet::is_hint_op (opstr.op))
+ return true;
+ if (opstr.op == OpCode_Subrs)
+ {
+ if (flatten_subrs)
+ return_trace (true);
+ else
+ return_trace (FontDict::serialize_offset2_op(c, OpCode_Subrs, subrsOffset));
+ }
+ else
+ return_trace (copy_opstr (c, opstr));
+ }
+
+ inline unsigned int calculate_serialized_size (const OpStr &opstr) const
+ {
+ if (drop_hints && DictOpSet::is_hint_op (opstr.op))
+ return 0;
+ if (opstr.op == OpCode_Subrs)
+ {
+ if (flatten_subrs)
+ return 0;
+ else
+ return OpCode_Size (OpCode_shortint) + 2 + OpCode_Size (OpCode_Subrs);
+ }
+ else
+ return opstr.str.len;
+ }
+
+ protected:
+ const bool drop_hints;
+ const bool flatten_subrs;
+};
+
template <typename ACCESSOR, typename ENV, typename OPSET>
struct SubrFlattener