mirror of
https://github.com/harfbuzz/harfbuzz.git
synced 2025-04-14 17:13:40 +00:00
[instancer-solver] add renormalizeValue() and store axis->distances map
This commit is contained in:
parent
d92a7a58d8
commit
165f3e60ac
5 changed files with 80 additions and 8 deletions
|
@ -228,6 +228,13 @@ struct AxisRecord
|
|||
return defaultValue.to_float ();
|
||||
}
|
||||
|
||||
TripleDistances get_triple_distances () const
|
||||
{
|
||||
float min, default_, max;
|
||||
get_coordinates (min, default_, max);
|
||||
return TripleDistances (min, default_, max);
|
||||
}
|
||||
|
||||
public:
|
||||
Tag axisTag; /* Tag identifying the design variation for the axis. */
|
||||
protected:
|
||||
|
|
|
@ -392,8 +392,47 @@ static inline float normalizeValue (float v, const Triple &triple, bool extrapol
|
|||
}
|
||||
}
|
||||
|
||||
static inline TripleDistances _reverse_triple_distances (const TripleDistances &v)
|
||||
{ return TripleDistances (v.positive, v.negative); }
|
||||
|
||||
float renormalizeValue (float v, const Triple &triple,
|
||||
const TripleDistances &triple_distances, bool extrapolate)
|
||||
{
|
||||
float lower = triple.minimum, def = triple.middle, upper = triple.maximum;
|
||||
assert (lower <= def && def <= upper);
|
||||
|
||||
if (!extrapolate)
|
||||
v = hb_max (hb_min (v, upper), lower);
|
||||
|
||||
if (v == def)
|
||||
return 0.f;
|
||||
|
||||
if (def < 0.f)
|
||||
return -renormalizeValue (-v, _reverse_negate (triple),
|
||||
_reverse_triple_distances (triple_distances), extrapolate);
|
||||
|
||||
/* default >= 0 and v != default */
|
||||
if (v > def)
|
||||
return (v - def) / (upper - def);
|
||||
|
||||
/* v < def */
|
||||
if (lower >= 0.f)
|
||||
return (v - def) / (def - lower);
|
||||
|
||||
/* lower < 0 and v < default */
|
||||
float total_distance = triple_distances.negative * (-lower) + triple_distances.positive * def;
|
||||
|
||||
float v_distance;
|
||||
if (v >= 0.f)
|
||||
v_distance = (def - v) * triple_distances.positive;
|
||||
else
|
||||
v_distance = (-v) * triple_distances.negative + triple_distances.positive * def;
|
||||
|
||||
return (-v_distance) /total_distance;
|
||||
}
|
||||
|
||||
result_t
|
||||
rebase_tent (Triple tent, Triple axisLimit)
|
||||
rebase_tent (Triple tent, Triple axisLimit, TripleDistances axis_triple_distances)
|
||||
{
|
||||
assert (-1.f <= axisLimit.minimum && axisLimit.minimum <= axisLimit.middle && axisLimit.middle <= axisLimit.maximum && axisLimit.maximum <= +1.f);
|
||||
assert (-2.f <= tent.minimum && tent.minimum <= tent.middle && tent.middle <= tent.maximum && tent.maximum <= +2.f);
|
||||
|
@ -401,7 +440,7 @@ rebase_tent (Triple tent, Triple axisLimit)
|
|||
|
||||
result_t sols = _solve (tent, axisLimit);
|
||||
|
||||
auto n = [&axisLimit] (float v) { return normalizeValue (v, axisLimit, true); };
|
||||
auto n = [&axisLimit, &axis_triple_distances] (float v) { return renormalizeValue (v, axisLimit, axis_triple_distances); };
|
||||
|
||||
result_t out;
|
||||
for (auto &p : sols)
|
||||
|
|
|
@ -27,6 +27,21 @@
|
|||
|
||||
#include "hb.hh"
|
||||
|
||||
/* pre-normalized distances */
|
||||
struct TripleDistances
|
||||
{
|
||||
TripleDistances (): negative (1.f), positive (1.f) {}
|
||||
TripleDistances (float neg_, float pos_): negative (neg_), positive (pos_) {}
|
||||
TripleDistances (float min, float default_, float max)
|
||||
{
|
||||
negative = default_ - min;
|
||||
positive = max - default_;
|
||||
}
|
||||
|
||||
float negative;
|
||||
float positive;
|
||||
};
|
||||
|
||||
struct Triple {
|
||||
|
||||
Triple () :
|
||||
|
@ -66,6 +81,7 @@ struct Triple {
|
|||
return current;
|
||||
}
|
||||
|
||||
|
||||
float minimum;
|
||||
float middle;
|
||||
float maximum;
|
||||
|
@ -74,6 +90,12 @@ struct Triple {
|
|||
using result_item_t = hb_pair_t<float, Triple>;
|
||||
using result_t = hb_vector_t<result_item_t>;
|
||||
|
||||
/* renormalize a normalized value v to the range of an axis,
|
||||
* considering the prenormalized distances as well as the new axis limits.
|
||||
* Ported from fonttools */
|
||||
HB_INTERNAL float renormalizeValue (float v, const Triple &triple,
|
||||
const TripleDistances &triple_distances,
|
||||
bool extrapolate = true);
|
||||
/* 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
|
||||
|
@ -85,6 +107,6 @@ using result_t = hb_vector_t<result_item_t>;
|
|||
* 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);
|
||||
HB_INTERNAL result_t rebase_tent (Triple tent, Triple axisLimit, TripleDistances axis_triple_distances);
|
||||
|
||||
#endif /* HB_SUBSET_INSTANCER_SOLVER_HH */
|
||||
|
|
|
@ -105,6 +105,8 @@ HB_SUBSET_PLAN_MEMBER (hb_vector_t<int>, normalized_coords)
|
|||
|
||||
//user specified axes range map
|
||||
HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<hb_tag_t, Triple>), user_axes_location)
|
||||
//axis->TripleDistances map (distances in the pre-normalized space)
|
||||
HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<hb_tag_t, TripleDistances>), axes_triple_distances)
|
||||
|
||||
//retained old axis index -> new axis index mapping in fvar axis array
|
||||
HB_SUBSET_PLAN_MEMBER (hb_map_t, axes_index_map)
|
||||
|
|
|
@ -930,12 +930,14 @@ _normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan)
|
|||
new_axis_idx++;
|
||||
}
|
||||
|
||||
if (plan->user_axes_location.has (axis_tag))
|
||||
Triple *axis_range;
|
||||
if (plan->user_axes_location.has (axis_tag, &axis_range))
|
||||
{
|
||||
Triple axis_range = plan->user_axes_location.get (axis_tag);
|
||||
int normalized_min = axis.normalize_axis_value (axis_range.minimum);
|
||||
int normalized_default = axis.normalize_axis_value (axis_range.middle);
|
||||
int normalized_max = axis.normalize_axis_value (axis_range.maximum);
|
||||
plan->axes_triple_distances.set (axis_tag, axis.get_triple_distances ());
|
||||
|
||||
int normalized_min = axis.normalize_axis_value (axis_range->minimum);
|
||||
int normalized_default = axis.normalize_axis_value (axis_range->middle);
|
||||
int normalized_max = axis.normalize_axis_value (axis_range->maximum);
|
||||
|
||||
if (has_avar && old_axis_idx < avar_axis_count)
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue