Use functions to get new gids. Avoid 0; fonttools drops it from cmap.

This commit is contained in:
Rod Sheeter 2018-02-12 14:29:23 -08:00
parent 1639bdd331
commit 1330edc4fe
4 changed files with 44 additions and 12 deletions

View File

@ -522,18 +522,25 @@ struct cmap
encodingRecord.sanitize (c, this)); encodingRecord.sanitize (c, this));
} }
inline void populate_groups(hb_prealloced_array_t<hb_codepoint_t> &codepoints, inline hb_bool_t populate_groups(hb_subset_plan_t *plan,
hb_prealloced_array_t<CmapSubtableLongGroup> *groups) const hb_prealloced_array_t<CmapSubtableLongGroup> *groups) const
{ {
CmapSubtableLongGroup *group = nullptr; CmapSubtableLongGroup *group = nullptr;
for (unsigned int i = 0; i < codepoints.len; i++) { for (unsigned int i = 0; i < plan->codepoints.len; i++) {
hb_codepoint_t cp = codepoints[i];
hb_codepoint_t cp = plan->codepoints[i];
if (!group || cp - 1 != group->endCharCode) if (!group || cp - 1 != group->endCharCode)
{ {
group = groups->push(); group = groups->push();
group->startCharCode.set(cp); group->startCharCode.set(cp);
group->endCharCode.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 } else
{ {
group->endCharCode.set(cp); group->endCharCode.set(cp);
@ -545,6 +552,8 @@ struct cmap
CmapSubtableLongGroup& group = (*groups)[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)); 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<CmapSubtableLongGroup> &groups, hb_bool_t _subset (hb_prealloced_array_t<CmapSubtableLongGroup> &groups,
@ -600,7 +609,10 @@ struct cmap
{ {
hb_auto_array_t<CmapSubtableLongGroup> groups; hb_auto_array_t<CmapSubtableLongGroup> groups;
populate_groups(plan->codepoints, &groups); if (unlikely(!populate_groups(plan, &groups)))
{
return nullptr;
}
// We now know how big our blob needs to be // We now know how big our blob needs to be
// TODO use APIs from the structs to get size? // TODO use APIs from the structs to get size?

View File

@ -38,6 +38,24 @@ _hb_codepoint_t_cmp (const void *pa, const void *pb)
return a < b ? -1 : a > b ? +1 : 0; 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_bool_t
hb_subset_plan_new_gid_for_old_id (hb_subset_plan_t *plan, hb_subset_plan_new_gid_for_old_id (hb_subset_plan_t *plan,
hb_codepoint_t old_gid, 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 // 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++) { for (unsigned int i = 0; i < plan->gids_to_retain_sorted.len; i++) {
if (plan->gids_to_retain_sorted[i] == old_gid) { 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; return true;
} }
} }
@ -109,10 +128,6 @@ _populate_gids_to_retain (hb_face_t *face,
*(old_gids_sorted.push ()) = 0; *(old_gids_sorted.push ()) = 0;
old_gids_sorted.qsort (_hb_codepoint_t_cmp); 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(Q1) expand with glyphs that make up complex glyphs
// TODO expand with glyphs reached by G* // TODO expand with glyphs reached by G*
// //

View File

@ -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 old_gid,
hb_codepoint_t *new_gid /* OUT */); 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_INTERNAL void
hb_subset_plan_destroy (hb_subset_plan_t *plan); hb_subset_plan_destroy (hb_subset_plan_t *plan);

View File

@ -124,7 +124,7 @@ _subset (hb_subset_plan_t *plan, hb_face_t *source)
hb_blob_destroy (source_blob); hb_blob_destroy (source_blob);
hb_tag_t tag = TableType::tableTag; 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; return result;
} }