From f33ad6d69216a983624e832177895481549bdc07 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 23 Oct 2018 14:31:51 -0700 Subject: [PATCH] [aat] Fix up previous commit and add files --- src/hb-aat-map.cc | 62 ++++++++++++++++++++++++++ src/hb-aat-map.hh | 106 +++++++++++++++++++++++++++++++++++++++++++++ src/hb-ot-map.cc | 1 + src/hb-ot-shape.cc | 15 +++++-- 4 files changed, 181 insertions(+), 3 deletions(-) create mode 100644 src/hb-aat-map.cc create mode 100644 src/hb-aat-map.hh diff --git a/src/hb-aat-map.cc b/src/hb-aat-map.cc new file mode 100644 index 000000000..f2736bfd1 --- /dev/null +++ b/src/hb-aat-map.cc @@ -0,0 +1,62 @@ +/* + * Copyright © 2009,2010 Red Hat, Inc. + * Copyright © 2010,2011,2013 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Red Hat Author(s): Behdad Esfahbod + * Google Author(s): Behdad Esfahbod + */ + +#include "hb-aat-map.hh" + +#include "hb-aat-layout.hh" + + +void hb_aat_map_builder_t::add_feature (hb_tag_t tag, + unsigned int value) +{ + const hb_aat_feature_mapping_t *mapping = hb_aat_layout_find_feature_mapping (tag); + if (!mapping) return; + + feature_info_t *info = features.push(); + info->type = mapping->aatFeatureType; + info->setting = value ? mapping->selectorToEnable : mapping->selectorToDisable; +} + +void +hb_aat_map_builder_t::compile (hb_aat_map_t &m, + const int *coords HB_UNUSED, + unsigned int num_coords HB_UNUSED) +{ + /* Sort features and merge duplicates */ + if (features.len) + { + features.qsort (); + unsigned int j = 0; + for (unsigned int i = 1; i < features.len; i++) + if (features[i].type != features[j].type) + features[++j] = features[i]; + features.shrink (j + 1); + } + + hb_aat_layout_compile_map (this, &m); +} diff --git a/src/hb-aat-map.hh b/src/hb-aat-map.hh new file mode 100644 index 000000000..846cdc1a9 --- /dev/null +++ b/src/hb-aat-map.hh @@ -0,0 +1,106 @@ +/* + * Copyright © 2018 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_AAT_MAP_HH +#define HB_AAT_MAP_HH + +#include "hb.hh" + + +struct hb_ot_shape_plan_t; + +struct hb_aat_map_t +{ + friend struct hb_aat_map_builder_t; + + public: + + inline void init (void) + { + memset (this, 0, sizeof (*this)); + chain_flags.init (); + } + inline void fini (void) + { + chain_flags.fini (); + } + + public: + hb_vector_t chain_flags; +}; + +struct hb_aat_map_builder_t +{ + public: + + HB_INTERNAL hb_aat_map_builder_t (hb_face_t *face_, + const hb_segment_properties_t *props_ HB_UNUSED) : + face (face_) + { + features.init (); + } + + ~hb_aat_map_builder_t (void) + { + features.fini (); + } + + HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value=1); + + HB_INTERNAL void compile (hb_aat_map_t &m, + const int *coords, + unsigned int num_coords); + + public: + struct feature_info_t + { + uint16_t type; + uint16_t setting; + unsigned seq; /* For stable sorting only. */ + + static int cmp (const void *pa, const void *pb) + { + const feature_info_t *a = (const feature_info_t *) pa; + const feature_info_t *b = (const feature_info_t *) pb; + return (a->type != b->type) ? (a->type < b->type ? -1 : 1) : + (a->seq < b->seq ? -1 : a->seq > b->seq ? 1 : 0); + } + + int cmp (const short unsigned int *ty) const + { + return (type != *ty) ? (type < *ty ? -1 : 1) : 0; + } + }; + + public: + hb_face_t *face; + + public: + hb_vector_t features; +}; + + +#endif /* HB_AAT_MAP_HH */ diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc index 82e989ef1..fd8109950 100644 --- a/src/hb-ot-map.cc +++ b/src/hb-ot-map.cc @@ -175,6 +175,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, } /* Sort features and merge duplicates */ + if (feature_infos.len) { feature_infos.qsort (); unsigned int j = 0; diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 23da56c2f..065b4d4bf 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -71,7 +71,8 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, plan.props = props; plan.shaper = shaper; map.compile (plan.map, coords, num_coords); - aat_map.compile (plan.aat_map, coords, num_coords); + if (apply_morx) + aat_map.compile (plan.aat_map, coords, num_coords); plan.frac_mask = plan.map.get_1_mask (HB_TAG ('f','r','a','c')); plan.numr_mask = plan.map.get_1_mask (HB_TAG ('n','u','m','r')); @@ -162,7 +163,6 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, unsigned int num_user_features) { hb_ot_map_builder_t *map = &planner->map; - hb_aat_map_builder_t *aat_map = &planner->aat_map; map->enable_feature (HB_TAG('r','v','r','n')); map->add_gsub_pause (nullptr); @@ -228,7 +228,16 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, (feature->start == HB_FEATURE_GLOBAL_START && feature->end == HB_FEATURE_GLOBAL_END) ? F_GLOBAL : F_NONE, feature->value); - aat_map->add_feature (feature->tag, feature->value); + } + + if (planner->apply_morx) + { + hb_aat_map_builder_t *aat_map = &planner->aat_map; + for (unsigned int i = 0; i < num_user_features; i++) + { + const hb_feature_t *feature = &user_features[i]; + aat_map->add_feature (feature->tag, feature->value); + } } }