summaryrefslogtreecommitdiffstats
path: root/gfx/harfbuzz/src/OT/glyf/SubsetGlyph.hh
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/harfbuzz/src/OT/glyf/SubsetGlyph.hh')
-rw-r--r--gfx/harfbuzz/src/OT/glyf/SubsetGlyph.hh152
1 files changed, 152 insertions, 0 deletions
diff --git a/gfx/harfbuzz/src/OT/glyf/SubsetGlyph.hh b/gfx/harfbuzz/src/OT/glyf/SubsetGlyph.hh
new file mode 100644
index 0000000000..26dc374eab
--- /dev/null
+++ b/gfx/harfbuzz/src/OT/glyf/SubsetGlyph.hh
@@ -0,0 +1,152 @@
+#ifndef OT_GLYF_SUBSETGLYPH_HH
+#define OT_GLYF_SUBSETGLYPH_HH
+
+
+#include "../../hb-open-type.hh"
+
+
+namespace OT {
+
+struct glyf_accelerator_t;
+
+namespace glyf_impl {
+
+
+struct SubsetGlyph
+{
+ hb_codepoint_t old_gid;
+ Glyph source_glyph;
+ hb_bytes_t dest_start; /* region of source_glyph to copy first */
+ hb_bytes_t dest_end; /* region of source_glyph to copy second */
+ bool allocated;
+
+ bool serialize (hb_serialize_context_t *c,
+ bool use_short_loca,
+ const hb_subset_plan_t *plan)
+ {
+ TRACE_SERIALIZE (this);
+
+ hb_bytes_t dest_glyph = dest_start.copy (c);
+ hb_bytes_t end_copy = dest_end.copy (c);
+ if (!end_copy.arrayZ || !dest_glyph.arrayZ) {
+ return false;
+ }
+
+ dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + end_copy.length);
+ unsigned int pad_length = use_short_loca ? padding () : 0;
+ DEBUG_MSG (SUBSET, nullptr, "serialize %u byte glyph, width %u pad %u", dest_glyph.length, dest_glyph.length + pad_length, pad_length);
+
+ HBUINT8 pad;
+ pad = 0;
+ while (pad_length > 0)
+ {
+ c->embed (pad);
+ pad_length--;
+ }
+
+ if (unlikely (!dest_glyph.length)) return_trace (true);
+
+ /* update components gids. */
+ for (auto &_ : Glyph (dest_glyph).get_composite_iterator ())
+ {
+ hb_codepoint_t new_gid;
+ if (plan->new_gid_for_old_gid (_.get_gid(), &new_gid))
+ const_cast<CompositeGlyphRecord &> (_).set_gid (new_gid);
+ }
+#ifndef HB_NO_VAR_COMPOSITES
+ for (auto &_ : Glyph (dest_glyph).get_var_composite_iterator ())
+ {
+ hb_codepoint_t new_gid;
+ if (plan->new_gid_for_old_gid (_.get_gid(), &new_gid))
+ const_cast<VarCompositeGlyphRecord &> (_).set_gid (new_gid);
+ }
+#endif
+
+#ifndef HB_NO_BEYOND_64K
+ auto it = Glyph (dest_glyph).get_composite_iterator ();
+ if (it)
+ {
+ /* lower GID24 to GID16 in components if possible.
+ *
+ * TODO: VarComposite. Not as critical, since VarComposite supports
+ * gid24 from the first version. */
+ char *p = it ? (char *) &*it : nullptr;
+ char *q = p;
+ const char *end = dest_glyph.arrayZ + dest_glyph.length;
+ while (it)
+ {
+ auto &rec = const_cast<CompositeGlyphRecord &> (*it);
+ ++it;
+
+ q += rec.get_size ();
+
+ rec.lower_gid_24_to_16 ();
+
+ unsigned size = rec.get_size ();
+
+ memmove (p, &rec, size);
+
+ p += size;
+ }
+ memmove (p, q, end - q);
+ p += end - q;
+
+ /* We want to shorten the glyph, but we can't do that without
+ * updating the length in the loca table, which is already
+ * written out :-(. So we just fill the rest of the glyph with
+ * harmless instructions, since that's what they will be
+ * interpreted as.
+ *
+ * Should move the lowering to _populate_subset_glyphs() to
+ * fix this issue. */
+
+ hb_memset (p, 0x7A /* TrueType instruction ROFF; harmless */, end - p);
+ p += end - p;
+ dest_glyph = hb_bytes_t (dest_glyph.arrayZ, p - (char *) dest_glyph.arrayZ);
+
+ // TODO: Padding; & trim serialized bytes.
+ // TODO: Update length in loca. Ugh.
+ }
+#endif
+
+ if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
+ Glyph (dest_glyph).drop_hints ();
+
+ if (plan->flags & HB_SUBSET_FLAGS_SET_OVERLAPS_FLAG)
+ Glyph (dest_glyph).set_overlaps_flag ();
+
+ return_trace (true);
+ }
+
+ bool compile_bytes_with_deltas (const hb_subset_plan_t *plan,
+ hb_font_t *font,
+ const glyf_accelerator_t &glyf)
+ {
+ allocated = source_glyph.compile_bytes_with_deltas (plan, font, glyf, dest_start, dest_end);
+ return allocated;
+ }
+
+ void free_compiled_bytes ()
+ {
+ if (likely (allocated)) {
+ allocated = false;
+ dest_start.fini ();
+ dest_end.fini ();
+ }
+ }
+
+ void drop_hints_bytes ()
+ { source_glyph.drop_hints_bytes (dest_start, dest_end); }
+
+ unsigned int length () const { return dest_start.length + dest_end.length; }
+ /* pad to 2 to ensure 2-byte loca will be ok */
+ unsigned int padding () const { return length () % 2; }
+ unsigned int padded_size () const { return length () + padding (); }
+};
+
+
+} /* namespace glyf_impl */
+} /* namespace OT */
+
+
+#endif /* OT_GLYF_SUBSETGLYPH_HH */