diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index b3a7b8b8e..4d32359df 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -522,18 +522,25 @@ struct cmap encodingRecord.sanitize (c, this)); } - inline void populate_groups(hb_prealloced_array_t &codepoints, - hb_prealloced_array_t *groups) const + inline hb_bool_t populate_groups(hb_subset_plan_t *plan, + hb_prealloced_array_t *groups) const { CmapSubtableLongGroup *group = nullptr; - for (unsigned int i = 0; i < codepoints.len; i++) { - hb_codepoint_t cp = codepoints[i]; + 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); - group->glyphID.set(i); // index in codepoints is new gid + 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); @@ -545,6 +552,8 @@ struct cmap 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; } hb_bool_t _subset (hb_prealloced_array_t &groups, @@ -600,7 +609,10 @@ struct cmap { hb_auto_array_t groups; - populate_groups(plan->codepoints, &groups); + if (unlikely(!populate_groups(plan, &groups))) + { + return nullptr; + } // We now know how big our blob needs to be // TODO use APIs from the structs to get size? diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index a06d38ae5..cc12abcae 100644 --- a/src/hb-subset-plan.cc +++ b/src/hb-subset-plan.cc @@ -38,6 +38,24 @@ _hb_codepoint_t_cmp (const void *pa, const void *pb) return a < b ? -1 : a > b ? +1 : 0; } +hb_bool_t +hb_subset_plan_new_gid_for_codepoint (hb_subset_plan_t *plan, + hb_codepoint_t codepoint, + hb_codepoint_t *new_gid) +{ + // TODO actual map, delete this garbage. + for (unsigned int i = 0; i < plan->codepoints.len; i++) + { + if (plan->codepoints[i] != codepoint) continue; + if (!hb_subset_plan_new_gid_for_old_id(plan, plan->gids_to_retain[i], new_gid)) + { + return false; + } + return true; + } + return false; +} + hb_bool_t hb_subset_plan_new_gid_for_old_id (hb_subset_plan_t *plan, hb_codepoint_t old_gid, @@ -46,7 +64,8 @@ hb_subset_plan_new_gid_for_old_id (hb_subset_plan_t *plan, // the index in old_gids is the new gid; only up to codepoints.len are valid for (unsigned int i = 0; i < plan->gids_to_retain_sorted.len; i++) { if (plan->gids_to_retain_sorted[i] == old_gid) { - *new_gid = i; + // +1: assign new gids from 1..N; 0 is special + *new_gid = i + 1; return true; } } @@ -109,10 +128,6 @@ _populate_gids_to_retain (hb_face_t *face, *(old_gids_sorted.push ()) = 0; old_gids_sorted.qsort (_hb_codepoint_t_cmp); - for (unsigned int i = 0; i < codepoints.len; i++) { - DEBUG_MSG(SUBSET, nullptr, " U+%04X, old_gid %d, new_gid %d", codepoints[i], old_gids[i], i); - } - // TODO(Q1) expand with glyphs that make up complex glyphs // TODO expand with glyphs reached by G* // diff --git a/src/hb-subset-plan.hh b/src/hb-subset-plan.hh index 410d9beca..09df7cddf 100644 --- a/src/hb-subset-plan.hh +++ b/src/hb-subset-plan.hh @@ -55,6 +55,11 @@ hb_subset_plan_new_gid_for_old_id(hb_subset_plan_t *plan, hb_codepoint_t old_gid, hb_codepoint_t *new_gid /* OUT */); +HB_INTERNAL hb_bool_t +hb_subset_plan_new_gid_for_codepoint(hb_subset_plan_t *plan, + hb_codepoint_t codepont, + hb_codepoint_t *new_gid /* OUT */); + HB_INTERNAL void hb_subset_plan_destroy (hb_subset_plan_t *plan); diff --git a/src/hb-subset.cc b/src/hb-subset.cc index d9a4d1258..e91d78000 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -124,7 +124,7 @@ _subset (hb_subset_plan_t *plan, hb_face_t *source) hb_blob_destroy (source_blob); hb_tag_t tag = TableType::tableTag; - DEBUG_MSG(SUBSET, nullptr, "Subset %c%c%c%c %s", HB_UNTAG(tag), result ? "success" : "FAILED!"); + DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset %s", HB_UNTAG(tag), result ? "success" : "FAILED!"); return result; }