diff options
Diffstat (limited to 'Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh')
-rw-r--r-- | Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh | 137 |
1 files changed, 129 insertions, 8 deletions
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh index b9d6e248ae9..02079898683 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh @@ -28,7 +28,7 @@ #define HB_OT_CMAP_TABLE_HH #include "hb-open-type-private.hh" - +#include "hb-subset-plan.hh" namespace OT { @@ -61,7 +61,7 @@ struct CmapSubtableFormat0 HBUINT16 format; /* Format number is set to 0. */ HBUINT16 lengthZ; /* Byte length of this subtable. */ HBUINT16 languageZ; /* Ignore. */ - HBUINT8 glyphIdArray[256];/* An array that maps character + HBUINT8 glyphIdArray[256];/* An array that maps character * code to glyph index values. */ public: DEFINE_SIZE_STATIC (6 + 256); @@ -193,6 +193,7 @@ struct CmapSubtableLongGroup { friend struct CmapSubtableFormat12; friend struct CmapSubtableFormat13; + friend struct cmap; int cmp (hb_codepoint_t codepoint) const { @@ -253,6 +254,8 @@ struct CmapSubtableFormat10 : CmapSubtableTrimmed<HBUINT32 > {}; template <typename T> struct CmapSubtableLongSegmented { + friend struct cmap; + inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const { int i = groups.bsearch (codepoint); @@ -268,6 +271,16 @@ struct CmapSubtableLongSegmented return_trace (c->check_struct (this) && groups.sanitize (c)); } + inline bool serialize (hb_serialize_context_t *c, + hb_prealloced_array_t<CmapSubtableLongGroup> &group_data) + { + TRACE_SERIALIZE (this); + if (unlikely (!c->extend_min (*this))) return_trace (false); + Supplier<CmapSubtableLongGroup> supplier (group_data.array, group_data.len); + if (unlikely (!groups.serialize (c, supplier, group_data.len))) return_trace (false); + return true; + } + protected: HBUINT16 format; /* Subtable format; set to 12. */ HBUINT16 reservedZ; /* Reserved; set to 0. */ @@ -422,12 +435,12 @@ struct CmapSubtable hb_codepoint_t *glyph) const { switch (u.format) { - case 0: return u.format0 .get_glyph(codepoint, glyph); - case 4: return u.format4 .get_glyph(codepoint, glyph); - case 6: return u.format6 .get_glyph(codepoint, glyph); - case 10: return u.format10.get_glyph(codepoint, glyph); - case 12: return u.format12.get_glyph(codepoint, glyph); - case 13: return u.format13.get_glyph(codepoint, glyph); + case 0: return u.format0 .get_glyph (codepoint, glyph); + case 4: return u.format4 .get_glyph (codepoint, glyph); + case 6: return u.format6 .get_glyph (codepoint, glyph); + case 10: return u.format10.get_glyph (codepoint, glyph); + case 12: return u.format12.get_glyph (codepoint, glyph); + case 13: return u.format13.get_glyph (codepoint, glyph); case 14: default: return false; } @@ -504,6 +517,114 @@ struct cmap encodingRecord.sanitize (c, this)); } + inline bool populate_groups (hb_subset_plan_t *plan, + hb_prealloced_array_t<CmapSubtableLongGroup> *groups) const + { + CmapSubtableLongGroup *group = nullptr; + for (unsigned int i = 0; i < plan->codepoints.len; i++) { + + hb_codepoint_t cp = plan->codepoints[i]; + if (!group || cp - 1 != group->endCharCode) + { + group = groups->push (); + group->startCharCode.set (cp); + group->endCharCode.set (cp); + hb_codepoint_t new_gid; + if (unlikely (!hb_subset_plan_new_gid_for_codepoint (plan, cp, &new_gid))) + { + DEBUG_MSG(SUBSET, nullptr, "Unable to find new gid for %04x", cp); + return false; + } + group->glyphID.set (new_gid); + } else + { + group->endCharCode.set (cp); + } + } + + DEBUG_MSG(SUBSET, nullptr, "cmap"); + for (unsigned int i = 0; i < groups->len; i++) { + CmapSubtableLongGroup& group = (*groups)[i]; + DEBUG_MSG(SUBSET, nullptr, " %d: U+%04X-U+%04X, gid %d-%d", i, (uint32_t) group.startCharCode, (uint32_t) group.endCharCode, (uint32_t) group.glyphID, (uint32_t) group.glyphID + ((uint32_t) group.endCharCode - (uint32_t) group.startCharCode)); + } + + return true; + } + + inline bool _subset (hb_prealloced_array_t<CmapSubtableLongGroup> &groups, + size_t dest_sz, + void *dest) const + { + hb_serialize_context_t c (dest, dest_sz); + + OT::cmap *cmap = c.start_serialize<OT::cmap> (); + if (unlikely (!c.extend_min (*cmap))) + { + return false; + } + + cmap->version.set (0); + + if (unlikely (!cmap->encodingRecord.serialize (&c, /* numTables */ 1))) return false; + + EncodingRecord &rec = cmap->encodingRecord[0]; + rec.platformID.set (3); // Windows + rec.encodingID.set (10); // Unicode UCS-4 + + /* capture offset to subtable */ + CmapSubtable &subtable = rec.subtable.serialize (&c, cmap); + + subtable.u.format.set (12); + + CmapSubtableFormat12 &format12 = subtable.u.format12; + if (unlikely (!c.extend_min (format12))) return false; + + format12.format.set (12); + format12.reservedZ.set (0); + format12.lengthZ.set (16 + 12 * groups.len); + + if (unlikely (!format12.serialize (&c, groups))) return false; + + c.end_serialize (); + + return true; + } + + inline bool subset (hb_subset_plan_t *plan) const + { + hb_auto_array_t<CmapSubtableLongGroup> groups; + + if (unlikely (!populate_groups (plan, &groups))) return false; + + // We now know how big our blob needs to be + // TODO use APIs from the structs to get size? + size_t dest_sz = 4 // header + + 8 // 1 EncodingRecord + + 16 // Format 12 header + + 12 * groups.len; // SequentialMapGroup records + void *dest = malloc (dest_sz); + if (unlikely (!dest)) { + DEBUG_MSG(SUBSET, nullptr, "Unable to alloc %lu for cmap subset output", (unsigned long) dest_sz); + return false; + } + + if (unlikely (!_subset (groups, dest_sz, dest))) + { + free (dest); + return false; + } + + // all done, write the blob into dest + hb_blob_t *cmap_prime = hb_blob_create ((const char *)dest, + dest_sz, + HB_MEMORY_MODE_READONLY, + dest, + free); + bool result = hb_subset_plan_add_table (plan, HB_OT_TAG_cmap, cmap_prime); + hb_blob_destroy (cmap_prime); + return result; + } + struct accelerator_t { inline void init (hb_face_t *face) |