src/hb-open-file-private.hh | 6 +- src/hb-ot-glyf-table.hh | 26 ++++++++---- src/hb-subset-glyf.cc | 93 ++++++++++++++++++++++++++++++++++++++++---- src/hb-subset.cc | 37 ++++++++++++----- 4 files changed, 133 insertions(+), 29 deletions(-)
New commits: commit c9acab3cfbe4a21e86ad309ebb452f103b1c1b04 Author: Behdad Esfahbod <beh...@behdad.org> Date: Wed Feb 7 17:12:55 2018 -0600 Whitespace diff --git a/src/hb-open-file-private.hh b/src/hb-open-file-private.hh index 1e5676e8..762783f3 100644 --- a/src/hb-open-file-private.hh +++ b/src/hb-open-file-private.hh @@ -64,9 +64,9 @@ typedef struct TableRecord Tag tag; /* 4-byte identifier. */ CheckSum checkSum; /* CheckSum for this table. */ - HBUINT32 offset; /* Offset from beginning of TrueType font + HBUINT32 offset; /* Offset from beginning of TrueType font * file. */ - HBUINT32 length; /* Length of this table. */ + HBUINT32 length; /* Length of this table. */ public: DEFINE_SIZE_STATIC (16); } OpenTypeTable; @@ -81,7 +81,7 @@ typedef struct OffsetTable { return tables[i]; } - inline unsigned int get_table_tags (unsigned int start_offset, + inline unsigned int get_table_tags (unsigned int start_offset, unsigned int *table_count, /* IN/OUT */ hb_tag_t *table_tags /* OUT */) const { commit 7fd0b61dee18380c302009f8be9cd68dadab7308 Author: Behdad Esfahbod <beh...@behdad.org> Date: Wed Feb 7 16:44:52 2018 -0600 [subset] Create new face and copy all tables to it test-subset fails now because subset-face does not know how to compile itself. diff --git a/src/hb-subset.cc b/src/hb-subset.cc index a1c6833e..61f38a0a 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -194,10 +194,9 @@ hb_subset_face_add_table (hb_face_t *face, hb_tag_t tag, hb_blob_t *blob) /** * hb_subset: + * @source: font face data to be subset. * @profile: profile to use for the subsetting. * @input: input to use for the subsetting. - * @face: font face data to be subset. - * @result: subsetting result. * * Subsets a font according to provided profile and input. **/ @@ -210,13 +209,32 @@ hb_subset (hb_face_t *source, hb_subset_plan_t *plan = hb_subset_plan_create (source, profile, input); + hb_face_t *face = hb_subset_face_create (); + + /* Copy tables to new face. */ + { + hb_tag_t table_tags[32]; + unsigned int offset = 0, count; + do { + count == ARRAY_LENGTH (table_tags); + hb_face_get_table_tags (source, offset, &count, table_tags); + for (unsigned int i = 0; i < count; i++) + { + hb_tag_t tag = table_tags[i]; + hb_blob_t *blob = hb_face_reference_table (source, tag); + hb_subset_face_add_table (face, tag, blob); + hb_blob_destroy (blob); + } + } while (count == ARRAY_LENGTH (table_tags)); + } + hb_codepoint_t old_gid = -1; - while (hb_set_next(plan->glyphs_to_retain, &old_gid)) { + while (hb_set_next (plan->glyphs_to_retain, &old_gid)) { hb_codepoint_t new_gid; - if (hb_subset_plan_new_gid_for_old_id(plan, old_gid, &new_gid)) { - DEBUG_MSG(SUBSET, nullptr, "Remap %d : %d", old_gid, new_gid); + if (hb_subset_plan_new_gid_for_old_id (plan, old_gid, &new_gid)) { + DEBUG_MSG (SUBSET, nullptr, "Remap %d : %d", old_gid, new_gid); } else { - DEBUG_MSG(SUBSET, nullptr, "Remap %d : DOOM! No new ID", old_gid); + DEBUG_MSG (SUBSET, nullptr, "Remap %d : DOOM! No new ID", old_gid); } } // TODO: @@ -226,16 +244,13 @@ hb_subset (hb_face_t *source, // - copy the table into the output. // - Fix header + table directory. - bool success = true; - hb_blob_t *glyf_prime = nullptr; if (hb_subset_glyf (plan, source, &glyf_prime)) { // TODO: write new glyf to new face. - } else { - success = false; } hb_blob_destroy (glyf_prime); hb_subset_plan_destroy (plan); - return success ? hb_face_reference (source) : nullptr; + + return face; } commit 4e1abe2ce0b5163cbbbb8f8be0e9f7deba5ab2cb Author: Garret Rieger <grie...@google.com> Date: Wed Feb 7 13:28:11 2018 -0800 Refactor subset glyf to remove multiple calls to glyf.fini() diff --git a/src/hb-subset-glyf.cc b/src/hb-subset-glyf.cc index e0ae5d80..6581754b 100644 --- a/src/hb-subset-glyf.cc +++ b/src/hb-subset-glyf.cc @@ -74,46 +74,30 @@ write_glyf_prime (const OT::glyf::accelerator_t &glyf, return true; } -/** - * hb_subset_glyf: - * Subsets the glyph table according to a provided plan. - * - * Return value: subsetted glyf table. - * - * Since: 1.7.5 - **/ bool -hb_subset_glyf (hb_subset_plan_t *plan, - hb_face_t *face, - hb_blob_t **glyf_prime /* OUT */) +_hb_subset_glyf (const OT::glyf::accelerator_t &glyf, + const char *glyf_data, + hb_set_t *glyphs_to_retain, + hb_blob_t **glyf_prime /* OUT */) { // TODO(grieger): Sanity check writes to make sure they are in-bounds. // TODO(grieger): Sanity check allocation size for the new table. // TODO(grieger): Subset loca simultaneously. - hb_blob_t *glyf_blob = OT::Sanitizer<OT::glyf>().sanitize (face->reference_table (HB_OT_TAG_glyf)); - const char *glyf_data = hb_blob_get_data(glyf_blob, nullptr); - - OT::glyf::accelerator_t glyf; - glyf.init(face); - unsigned int glyf_prime_size; if (!calculate_glyf_prime_size (glyf, - plan->glyphs_to_retain, + glyphs_to_retain, &glyf_prime_size)) { - glyf.fini(); return false; } char *glyf_prime_data = (char *) calloc (glyf_prime_size, 1); - if (!write_glyf_prime (glyf, glyf_data, plan->glyphs_to_retain, glyf_prime_size, + if (!write_glyf_prime (glyf, glyf_data, glyphs_to_retain, glyf_prime_size, glyf_prime_data)) { - glyf.fini(); free (glyf_prime_data); return false; } - glyf.fini(); *glyf_prime = hb_blob_create (glyf_prime_data, glyf_prime_size, HB_MEMORY_MODE_READONLY, @@ -121,3 +105,27 @@ hb_subset_glyf (hb_subset_plan_t *plan, free); return true; } + +/** + * hb_subset_glyf: + * Subsets the glyph table according to a provided plan. + * + * Return value: subsetted glyf table. + * + * Since: 1.7.5 + **/ +bool +hb_subset_glyf (hb_subset_plan_t *plan, + hb_face_t *face, + hb_blob_t **glyf_prime /* OUT */) +{ + hb_blob_t *glyf_blob = OT::Sanitizer<OT::glyf>().sanitize (face->reference_table (HB_OT_TAG_glyf)); + const char *glyf_data = hb_blob_get_data(glyf_blob, nullptr); + + OT::glyf::accelerator_t glyf; + glyf.init(face); + bool result = _hb_subset_glyf (glyf, glyf_data, plan->glyphs_to_retain, glyf_prime); + glyf.fini(); + + return result; +} commit 0a5d1440f829f07454592adde9dd3aa93ad74442 Author: Garret Rieger <grie...@google.com> Date: Wed Feb 7 13:09:54 2018 -0800 Add implementation of glyf subsetting. diff --git a/src/hb-subset-glyf.cc b/src/hb-subset-glyf.cc index 5a3dff6d..e0ae5d80 100644 --- a/src/hb-subset-glyf.cc +++ b/src/hb-subset-glyf.cc @@ -24,9 +24,56 @@ * Google Author(s): Garret Rieger */ +#include "hb-open-type-private.hh" #include "hb-ot-glyf-table.hh" +#include "hb-set.h" #include "hb-subset-glyf.hh" +bool +calculate_glyf_prime_size (const OT::glyf::accelerator_t &glyf, + hb_set_t *glyph_ids, + unsigned int *size /* OUT */) +{ + unsigned int total = 0; + hb_codepoint_t next_glyph = -1; + while (hb_set_next(glyph_ids, &next_glyph)) { + unsigned int start_offset, end_offset; + if (!glyf.get_offsets (next_glyph, &start_offset, &end_offset)) { + *size = 0; + return false; + } + + total += end_offset - start_offset; + } + + *size = total; + return true; +} + +bool +write_glyf_prime (const OT::glyf::accelerator_t &glyf, + const char *glyf_data, + hb_set_t *glyph_ids, + int glyf_prime_size, + char *glyf_prime_data /* OUT */) +{ + char *glyf_prime_data_next = glyf_prime_data; + + hb_codepoint_t next_glyph = -1; + while (hb_set_next(glyph_ids, &next_glyph)) { + unsigned int start_offset, end_offset; + if (!glyf.get_offsets (next_glyph, &start_offset, &end_offset)) { + return false; + } + + int length = end_offset - start_offset; + memcpy (glyf_prime_data_next, glyf_data + start_offset, length); + glyf_prime_data_next += length; + } + + return true; +} + /** * hb_subset_glyf: * Subsets the glyph table according to a provided plan. @@ -40,13 +87,37 @@ hb_subset_glyf (hb_subset_plan_t *plan, hb_face_t *face, hb_blob_t **glyf_prime /* OUT */) { - OT::glyf::accelerator_t glyf_accelerator; - glyf_accelerator.init(face); + // TODO(grieger): Sanity check writes to make sure they are in-bounds. + // TODO(grieger): Sanity check allocation size for the new table. + // TODO(grieger): Subset loca simultaneously. + + hb_blob_t *glyf_blob = OT::Sanitizer<OT::glyf>().sanitize (face->reference_table (HB_OT_TAG_glyf)); + const char *glyf_data = hb_blob_get_data(glyf_blob, nullptr); + + OT::glyf::accelerator_t glyf; + glyf.init(face); - // TODO + unsigned int glyf_prime_size; + if (!calculate_glyf_prime_size (glyf, + plan->glyphs_to_retain, + &glyf_prime_size)) { + glyf.fini(); + return false; + } - glyf_accelerator.fini(); + char *glyf_prime_data = (char *) calloc (glyf_prime_size, 1); + if (!write_glyf_prime (glyf, glyf_data, plan->glyphs_to_retain, glyf_prime_size, + glyf_prime_data)) { + glyf.fini(); + free (glyf_prime_data); + return false; + } - *glyf_prime = hb_blob_get_empty (); + glyf.fini(); + *glyf_prime = hb_blob_create (glyf_prime_data, + glyf_prime_size, + HB_MEMORY_MODE_READONLY, + glyf_prime_data, + free); return true; } commit 05d65baa1bb64664ba838993fd35f3899d52eb8d Author: Garret Rieger <grie...@google.com> Date: Wed Feb 7 10:55:30 2018 -0800 Extract glyf offset calculation into it's own method. diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh index 67143c63..e6b07a86 100644 --- a/src/hb-ot-glyf-table.hh +++ b/src/hb-ot-glyf-table.hh @@ -122,29 +122,39 @@ struct glyf hb_blob_destroy (glyf_blob); } - inline bool get_extents (hb_codepoint_t glyph, - hb_glyph_extents_t *extents) const + inline bool get_offsets (hb_codepoint_t glyph, + unsigned int *start_offset /* OUT */, + unsigned int *end_offset /* OUT */) const { if (unlikely (glyph >= num_glyphs)) return false; - unsigned int start_offset, end_offset; if (short_offset) { const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataX; - start_offset = 2 * offsets[glyph]; - end_offset = 2 * offsets[glyph + 1]; + *start_offset = 2 * offsets[glyph]; + *end_offset = 2 * offsets[glyph + 1]; } else { const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataX; - start_offset = offsets[glyph]; - end_offset = offsets[glyph + 1]; + *start_offset = offsets[glyph]; + *end_offset = offsets[glyph + 1]; } - if (start_offset > end_offset || end_offset > glyf_len) + if (*start_offset > *end_offset || *end_offset > glyf_len) return false; + return true; + } + + inline bool get_extents (hb_codepoint_t glyph, + hb_glyph_extents_t *extents) const + { + unsigned int start_offset, end_offset; + if (!get_offsets (glyph, &start_offset, &end_offset)) + return false; + if (end_offset - start_offset < GlyphHeader::static_size) return true; /* Empty glyph; zero extents. */ _______________________________________________ HarfBuzz mailing list HarfBuzz@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/harfbuzz