diff --git a/src/hb-ot-os2-table.hh b/src/hb-ot-os2-table.hh index 5bed47013ea352662f067db2af68737f915934c3..f80a05d700b63664c2fa5be406eeb9ce3a4d60d8 100644 --- a/src/hb-ot-os2-table.hh +++ b/src/hb-ot-os2-table.hh @@ -49,6 +49,51 @@ struct os2 return_trace (c->check_struct (this)); } + inline hb_blob_t * subset (hb_subset_plan_t *plan, hb_face_t *source) const + { + hb_blob_t *os2_blob = OT::Sanitizer().sanitize (hb_face_reference_table (source, HB_OT_TAG_os2)); + hb_blob_t *os2_prime_blob = hb_blob_create_sub_blob (os2_blob, 0, -1); + hb_blob_destroy (os2_blob); + + OT::os2 *os2_prime = (OT::os2 *) hb_blob_get_data_writable (os2_prime_blob, nullptr); + if (unlikely (!os2_prime)) { + hb_blob_destroy (os2_prime_blob); + return nullptr; + } + + uint16_t min_cp, max_cp; + find_min_and_max_codepoint (plan, &min_cp, &max_cp); + os2_prime->usFirstCharIndex.set (min_cp); + os2_prime->usLastCharIndex.set (max_cp); + + return os2_prime_blob; + } + + static inline void find_min_and_max_codepoint (hb_subset_plan_t *plan, + uint16_t *min_cp, /* OUT */ + uint16_t *max_cp /* OUT */) + { + hb_codepoint_t min = -1, max = 0; + + for (int i = 0; i < plan->codepoints.len; i++) { + hb_codepoint_t cp = plan->codepoints[i]; + if (cp < min) { + min = cp; + } + if (cp > max) { + max = cp; + } + } + + if (min > 0xFFFF) + min = 0xFFFF; + if (max > 0xFFFF) + max = 0xFFFF; + + *min_cp = min; + *max_cp = max; + } + public: HBUINT16 version; diff --git a/src/hb-subset.cc b/src/hb-subset.cc index e91d7800019587f342898287724a8f6fad1f55a6..15730bf5abaa391d4fc38d160e36892af0187722 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -38,6 +38,7 @@ #include "hb-ot-glyf-table.hh" #include "hb-ot-head-table.hh" #include "hb-ot-maxp-table.hh" +#include "hb-ot-os2-table.hh" #ifndef HB_NO_VISIBILITY @@ -349,6 +350,9 @@ _subset_table (hb_subset_plan_t *plan, case HB_OT_TAG_cmap: dest_blob = _subset (plan, source); break; + case HB_OT_TAG_os2: + dest_blob = _subset (plan, source); + break; default: dest_blob = source_blob; break; @@ -360,17 +364,17 @@ _subset_table (hb_subset_plan_t *plan, } static bool -_should_drop_table(hb_tag_t tag) +_should_drop_table(hb_tag_t tag) { switch (tag) { - case HB_TAG('G', 'D', 'E', 'F'): /* temporary */ - case HB_TAG('G', 'P', 'O', 'S'): /* temporary */ - case HB_TAG('G', 'S', 'U', 'B'): /* temporary */ - case HB_TAG('d', 's', 'i', 'g'): + case HB_TAG ('G', 'D', 'E', 'F'): /* temporary */ + case HB_TAG ('G', 'P', 'O', 'S'): /* temporary */ + case HB_TAG ('G', 'S', 'U', 'B'): /* temporary */ + case HB_TAG ('d', 's', 'i', 'g'): return true; default: return false; - } + } } /**