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 serializeOT::glyf_impl::SubsetGlyph22 bool serialize (hb_serialize_context_t *c, 23 bool use_short_loca, 24 const hb_subset_plan_t *plan, 25 hb_font_t *font) 26 { 27 TRACE_SERIALIZE (this); 28 29 if (font) 30 { 31 const OT::glyf_accelerator_t &glyf = *font->face->table.glyf; 32 if (!this->compile_bytes_with_deltas (plan, font, glyf)) 33 return_trace (false); 34 } 35 36 hb_bytes_t dest_glyph = dest_start.copy (c); 37 dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + dest_end.copy (c).length); 38 unsigned int pad_length = use_short_loca ? padding () : 0; 39 DEBUG_MSG (SUBSET, nullptr, "serialize %d byte glyph, width %d pad %d", dest_glyph.length, dest_glyph.length + pad_length, pad_length); 40 41 HBUINT8 pad; 42 pad = 0; 43 while (pad_length > 0) 44 { 45 c->embed (pad); 46 pad_length--; 47 } 48 49 if (unlikely (!dest_glyph.length)) return_trace (true); 50 51 /* update components gids */ 52 for (auto &_ : Glyph (dest_glyph).get_composite_iterator ()) 53 { 54 hb_codepoint_t new_gid; 55 if (plan->new_gid_for_old_gid (_.get_gid(), &new_gid)) 56 const_cast<CompositeGlyphRecord &> (_).set_gid (new_gid); 57 } 58 59 if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING) 60 Glyph (dest_glyph).drop_hints (); 61 62 if (plan->flags & HB_SUBSET_FLAGS_SET_OVERLAPS_FLAG) 63 Glyph (dest_glyph).set_overlaps_flag (); 64 65 return_trace (true); 66 } 67 compile_bytes_with_deltasOT::glyf_impl::SubsetGlyph68 bool compile_bytes_with_deltas (const hb_subset_plan_t *plan, 69 hb_font_t *font, 70 const glyf_accelerator_t &glyf) 71 { return source_glyph.compile_bytes_with_deltas (plan, font, glyf, dest_start, dest_end); } 72 free_compiled_bytesOT::glyf_impl::SubsetGlyph73 void free_compiled_bytes () 74 { 75 dest_start.fini (); 76 dest_end.fini (); 77 } 78 drop_hints_bytesOT::glyf_impl::SubsetGlyph79 void drop_hints_bytes () 80 { source_glyph.drop_hints_bytes (dest_start, dest_end); } 81 lengthOT::glyf_impl::SubsetGlyph82 unsigned int length () const { return dest_start.length + dest_end.length; } 83 /* pad to 2 to ensure 2-byte loca will be ok */ paddingOT::glyf_impl::SubsetGlyph84 unsigned int padding () const { return length () % 2; } padded_sizeOT::glyf_impl::SubsetGlyph85 unsigned int padded_size () const { return length () + padding (); } 86 }; 87 88 89 } /* namespace glyf_impl */ 90 } /* namespace OT */ 91 92 93 #endif /* OT_GLYF_SUBSETGLYPH_HH */ 94