diff --git a/src/Makefile.sources b/src/Makefile.sources index 85537a58a..5ad5c68ac 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -358,6 +358,7 @@ HB_SUBSET_sources = \ hb-subset-cff2.hh \ hb-subset-input.cc \ hb-subset-input.hh \ + hb-subset-instancer-solver.hh \ hb-subset-instancer-solver.cc \ hb-subset-accelerator.hh \ hb-subset-plan.cc \ diff --git a/src/hb-subset-input.cc b/src/hb-subset-input.cc index 16ce657a0..e14044cfb 100644 --- a/src/hb-subset-input.cc +++ b/src/hb-subset-input.cc @@ -438,7 +438,8 @@ hb_subset_input_pin_axis_to_default (hb_subset_input_t *input, if (!hb_ot_var_find_axis_info (face, axis_tag, &axis_info)) return false; - return input->axes_location.set (axis_tag, axis_info.default_value); + float default_val = axis_info.default_value; + return input->axes_location.set (axis_tag, Triple (default_val, default_val, default_val)); } /** @@ -468,7 +469,7 @@ hb_subset_input_pin_axis_location (hb_subset_input_t *input, return false; float val = hb_clamp(axis_value, axis_info.min_value, axis_info.max_value); - return input->axes_location.set (axis_tag, val); + return input->axes_location.set (axis_tag, Triple (val, val, val)); } /** @@ -508,7 +509,7 @@ hb_subset_input_set_axis_range (hb_subset_input_t *input, float new_min_val = hb_clamp(axis_min_value, axis_info.min_value, axis_info.max_value); float new_max_val = hb_clamp(axis_max_value, axis_info.min_value, axis_info.max_value); float new_default_val = hb_clamp(axis_info.default_value, new_min_val, new_max_val); - return input->axes_location.set (axis_tag, new_default_val); + return input->axes_location.set (axis_tag, Triple (new_min_val, new_default_val, new_max_val)); } #endif diff --git a/src/hb-subset-input.hh b/src/hb-subset-input.hh index 1970f795b..6ae311e61 100644 --- a/src/hb-subset-input.hh +++ b/src/hb-subset-input.hh @@ -35,6 +35,7 @@ #include "hb-set.hh" #include "hb-cplusplus.hh" #include "hb-font.hh" +#include "hb-subset-instancer-solver.hh" struct hb_ot_name_record_ids_t { @@ -118,7 +119,7 @@ struct hb_subset_input_t // If set loca format will always be the long version. bool force_long_loca = false; - hb_hashmap_t axes_location; + hb_hashmap_t axes_location; hb_map_t glyph_map; #ifdef HB_EXPERIMENTAL_API hb_hashmap_t name_table_overrides; diff --git a/src/hb-subset-instancer-solver.cc b/src/hb-subset-instancer-solver.cc index 7a2735c52..bc1b37965 100644 --- a/src/hb-subset-instancer-solver.cc +++ b/src/hb-subset-instancer-solver.cc @@ -22,7 +22,7 @@ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ -#include "hb.hh" +#include "hb-subset-instancer-solver.hh" /* This file is a straight port of the following: * @@ -35,26 +35,6 @@ constexpr static float EPSILON = 1.f / (1 << 14); constexpr static float MAX_F2DOT14 = float (0x7FFF) / (1 << 14); -struct Triple { - - Triple () : - minimum (0.f), middle (0.f), maximum (0.f) {} - - Triple (float minimum_, float middle_, float maximum_) : - minimum (minimum_), middle (middle_), maximum (maximum_) {} - - bool operator == (const Triple &o) const - { - return minimum == o.minimum && - middle == o.middle && - maximum == o.maximum; - } - - float minimum; - float middle; - float maximum; -}; - static inline Triple _reverse_negate(const Triple &v) { return {-v.maximum, -v.middle, -v.minimum}; } @@ -82,10 +62,6 @@ static inline float supportScalar (float coord, const Triple &tent) return (end - coord) / (end - peak); } - -using result_item_t = hb_pair_t; -using result_t = hb_vector_t; - static inline result_t _solve (Triple tent, Triple axisLimit, bool negative = false) { @@ -422,19 +398,6 @@ static inline float normalizeValue (float v, const Triple &triple, bool extrapol } } -/* Given a tuple (lower,peak,upper) "tent" and new axis limits - * (axisMin,axisDefault,axisMax), solves how to represent the tent - * under the new axis configuration. All values are in normalized - * -1,0,+1 coordinate system. Tent values can be outside this range. - * - * Return value: a list of tuples. Each tuple is of the form - * (scalar,tent), where scalar is a multipler to multiply any - * delta-sets by, and tent is a new tent for that output delta-set. - * If tent value is Triple{}, that is a special deltaset that should - * be always-enabled (called "gain"). - */ -HB_INTERNAL result_t rebase_tent (Triple tent, Triple axisLimit); - result_t rebase_tent (Triple tent, Triple axisLimit) { diff --git a/src/hb-subset-instancer-solver.hh b/src/hb-subset-instancer-solver.hh new file mode 100644 index 000000000..842ea73a9 --- /dev/null +++ b/src/hb-subset-instancer-solver.hh @@ -0,0 +1,69 @@ +/* + * Copyright © 2023 Behdad Esfahbod + * + * 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. + */ + +#ifndef HB_SUBSET_INSTANCER_SOLVER_HH +#define HB_SUBSET_INSTANCER_SOLVER_HH + +#include "hb.hh" + +struct Triple { + + Triple () : + minimum (0.f), middle (0.f), maximum (0.f) {} + + Triple (float minimum_, float middle_, float maximum_) : + minimum (minimum_), middle (middle_), maximum (maximum_) {} + + bool operator == (const Triple &o) const + { + return minimum == o.minimum && + middle == o.middle && + maximum == o.maximum; + } + + bool is_point () const + { return minimum == middle && middle == maximum; } + + float minimum; + float middle; + float maximum; +}; + +using result_item_t = hb_pair_t; +using result_t = hb_vector_t; + +/* Given a tuple (lower,peak,upper) "tent" and new axis limits + * (axisMin,axisDefault,axisMax), solves how to represent the tent + * under the new axis configuration. All values are in normalized + * -1,0,+1 coordinate system. Tent values can be outside this range. + * + * Return value: a list of tuples. Each tuple is of the form + * (scalar,tent), where scalar is a multipler to multiply any + * delta-sets by, and tent is a new tent for that output delta-set. + * If tent value is Triple{}, that is a special deltaset that should + * be always-enabled (called "gain"). + */ +HB_INTERNAL result_t rebase_tent (Triple tent, Triple axisLimit); + +#endif /* HB_SUBSET_INSTANCER_SOLVER_HH */ diff --git a/src/hb-subset-plan-member-list.hh b/src/hb-subset-plan-member-list.hh index acf508c32..6ebd7fdc1 100644 --- a/src/hb-subset-plan-member-list.hh +++ b/src/hb-subset-plan-member-list.hh @@ -97,12 +97,12 @@ HB_SUBSET_PLAN_MEMBER (hb_vector_t, gdef_varstore_inner_maps) HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(>), sanitized_table_cache) -//normalized axes location map -HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(), axes_location) +//normalized axes range map +HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(), axes_location) HB_SUBSET_PLAN_MEMBER (hb_vector_t, normalized_coords) -//user specified axes location map -HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(), user_axes_location) +//user specified axes range map +HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(), user_axes_location) //retained old axis index -> new axis index mapping in fvar axis array HB_SUBSET_PLAN_MEMBER (hb_map_t, axes_index_map) diff --git a/src/hb-subset-plan.hh b/src/hb-subset-plan.hh index 19470ff83..7559aa289 100644 --- a/src/hb-subset-plan.hh +++ b/src/hb-subset-plan.hh @@ -114,6 +114,10 @@ struct hb_subset_plan_t bool pinned_at_default; bool has_seac; + // whether to insert a catch-all FeatureVariationRecord + bool gsub_insert_catch_all_feature_variation_rec; + bool gpos_insert_catch_all_feature_variation_rec; + #define HB_SUBSET_PLAN_MEMBER(Type, Name) Type Name; #include "hb-subset-plan-member-list.hh" #undef HB_SUBSET_PLAN_MEMBER diff --git a/src/meson.build b/src/meson.build index 90735cb7e..188f7712c 100644 --- a/src/meson.build +++ b/src/meson.build @@ -358,6 +358,7 @@ hb_subset_sources = files( 'hb-subset-cff2.hh', 'hb-subset-input.cc', 'hb-subset-input.hh', + 'hb-subset-instancer-solver.hh', 'hb-subset-instancer-solver.cc', 'hb-subset-plan.cc', 'hb-subset-plan.hh',