tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

SubsetGlyph.hh (3815B)


      1 #ifndef OT_GLYF_SUBSETGLYPH_HH
      2 #define OT_GLYF_SUBSETGLYPH_HH
      3 
      4 
      5 #include "../../hb-open-type.hh"
      6 
      7 
      8 namespace OT {
      9 
     10 struct glyf_accelerator_t;
     11 
     12 namespace glyf_impl {
     13 
     14 
     15 struct SubsetGlyph
     16 {
     17  hb_codepoint_t old_gid;
     18  Glyph source_glyph;
     19  hb_bytes_t dest_start;  /* region of source_glyph to copy first */
     20  hb_bytes_t dest_end;    /* region of source_glyph to copy second */
     21  bool allocated;
     22 
     23  bool serialize (hb_serialize_context_t *c,
     24 	  bool use_short_loca,
     25 	  const hb_subset_plan_t *plan) const
     26  {
     27    TRACE_SERIALIZE (this);
     28 
     29    hb_bytes_t dest_glyph = dest_start.copy (c);
     30    hb_bytes_t end_copy = dest_end.copy (c);
     31    if (!end_copy.arrayZ || !dest_glyph.arrayZ) {
     32      return false;
     33    }
     34 
     35    dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + end_copy.length);
     36    unsigned int pad_length = use_short_loca ? padding () : 0;
     37    DEBUG_MSG (SUBSET, nullptr, "serialize %u byte glyph, width %u pad %u", dest_glyph.length, dest_glyph.length + pad_length, pad_length);
     38 
     39    HBUINT8 pad;
     40    pad = 0;
     41    while (pad_length > 0)
     42    {
     43      (void) c->embed (pad);
     44      pad_length--;
     45    }
     46 
     47    if (unlikely (!dest_glyph.length)) return_trace (true);
     48 
     49    /* update components gids. */
     50    for (auto &_ : Glyph (dest_glyph).get_composite_iterator ())
     51    {
     52      hb_codepoint_t new_gid;
     53      if (plan->new_gid_for_old_gid (_.get_gid(), &new_gid))
     54 const_cast<CompositeGlyphRecord &> (_).set_gid (new_gid);
     55    }
     56 
     57 #ifndef HB_NO_BEYOND_64K
     58    auto it = Glyph (dest_glyph).get_composite_iterator ();
     59    if (it)
     60    {
     61      /* lower GID24 to GID16 in components if possible. */
     62      char *p = it ? (char *) &*it : nullptr;
     63      char *q = p;
     64      const char *end = dest_glyph.arrayZ + dest_glyph.length;
     65      while (it)
     66      {
     67 auto &rec = const_cast<CompositeGlyphRecord &> (*it);
     68 ++it;
     69 
     70 q += rec.get_size ();
     71 
     72 rec.lower_gid_24_to_16 ();
     73 
     74 unsigned size = rec.get_size ();
     75 
     76 memmove (p, &rec, size);
     77 
     78 p += size;
     79      }
     80      memmove (p, q, end - q);
     81      p += end - q;
     82 
     83      /* We want to shorten the glyph, but we can't do that without
     84       * updating the length in the loca table, which is already
     85       * written out :-(.  So we just fill the rest of the glyph with
     86       * harmless instructions, since that's what they will be
     87       * interpreted as.
     88       *
     89       * Should move the lowering to _populate_subset_glyphs() to
     90       * fix this issue. */
     91 
     92      hb_memset (p, 0x7A /* TrueType instruction ROFF; harmless */, end - p);
     93      p += end - p;
     94      dest_glyph = hb_bytes_t (dest_glyph.arrayZ, p - (char *) dest_glyph.arrayZ);
     95 
     96      // TODO: Padding; & trim serialized bytes.
     97      // TODO: Update length in loca. Ugh.
     98    }
     99 #endif
    100 
    101    if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
    102      Glyph (dest_glyph).drop_hints ();
    103 
    104    if (plan->flags & HB_SUBSET_FLAGS_SET_OVERLAPS_FLAG)
    105      Glyph (dest_glyph).set_overlaps_flag ();
    106 
    107    return_trace (true);
    108  }
    109 
    110  bool compile_bytes_with_deltas (const hb_subset_plan_t *plan,
    111                                  hb_font_t *font,
    112                                  const glyf_accelerator_t &glyf)
    113  {
    114    allocated = source_glyph.compile_bytes_with_deltas (plan, font, glyf, dest_start, dest_end);
    115    return allocated;
    116  }
    117 
    118  void free_compiled_bytes ()
    119  {
    120    if (likely (allocated)) {
    121      allocated = false;
    122      dest_start.fini ();
    123      dest_end.fini ();
    124    }
    125  }
    126 
    127  void drop_hints_bytes ()
    128  { source_glyph.drop_hints_bytes (dest_start, dest_end); }
    129 
    130  unsigned int      length () const { return dest_start.length + dest_end.length; }
    131  /* pad to 2 to ensure 2-byte loca will be ok */
    132  unsigned int     padding () const { return length () % 2; }
    133  unsigned int padded_size () const { return length () + padding (); }
    134 };
    135 
    136 
    137 } /* namespace glyf_impl */
    138 } /* namespace OT */
    139 
    140 
    141 #endif /* OT_GLYF_SUBSETGLYPH_HH */