summaryrefslogtreecommitdiff
path: root/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh
diff options
context:
space:
mode:
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.hh137
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)