From b937edfb148d28421f97db7c3c81e2253019e469 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 1 Mar 2023 10:44:57 -0700 Subject: [PATCH] [justify] Add min/max target_width Speeds up solving when some slack available. --- src/hb-algs.hh | 8 +++++--- src/hb-shape.cc | 32 ++++++++++++++++++-------------- src/hb-shape.h | 3 ++- util/shape-options.hh | 6 ++++-- 4 files changed, 29 insertions(+), 20 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 05ca3ec9d..cf9403134 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -1357,7 +1357,8 @@ double solve_itp (func_t f, double epsilon, unsigned n0, double k1, - double &ya, double &yb) + double min_y, double max_y, + double &ya, double &yb, double &y) { unsigned n1_2 = (unsigned) (hb_max (ceil (log2 ((b - a) / epsilon)) - 1.0, 0.0)); unsigned nmax = n0 + n1_2; @@ -1377,18 +1378,19 @@ double solve_itp (func_t f, double xt = delta <= fabs (x1_2 - xf) ? xf + delta * sigma_sign : x1_2; double xitp = fabs (xt - x1_2) <= r ? xt : x1_2 - r * sigma_sign; double yitp = f (xitp); - if (yitp > 0.0) + if (yitp > max_y) { b = xitp; yb = yitp; } - else if (yitp < 0.0) + else if (yitp < min_y) { a = xitp; ya = yitp; } else { + y = yitp; return xitp; } scaled_epsilon *= 0.5; diff --git a/src/hb-shape.cc b/src/hb-shape.cc index e580298d1..d04cc214b 100644 --- a/src/hb-shape.cc +++ b/src/hb-shape.cc @@ -228,14 +228,15 @@ hb_shape_justify (hb_font_t *font, const hb_feature_t *features, unsigned int num_features, const char * const *shaper_list, - float target_width, + float min_target_width, + float max_target_width, float *width, /* IN/OUT */ hb_tag_t *var_tag, /* OUT */ float *var_value /* OUT */) { // TODO Negative font scales? - if (target_width == *width) + if (min_target_width <= *width && *width <= max_target_width) return hb_shape_full (font, buffer, features, num_features, shaper_list); @@ -287,13 +288,13 @@ hb_shape_justify (hb_font_t *font, *width = buffer_width (buffer); } - if (target_width == *width) + if (min_target_width <= *width && *width <= max_target_width) return true; double a, b, ya, yb; - if (*width < target_width) + if (*width < min_target_width) { - ya = *width - target_width; + ya = *width; a = axis_info.default_value; b = axis_info.max_value; @@ -303,16 +304,16 @@ hb_shape_justify (hb_font_t *font, features, num_features, shaper_list)) return false; - yb = buffer_width (buffer) - target_width; + yb = buffer_width (buffer); if (yb <= 0) { - *width = (float) yb + target_width; + *width = (float) yb; return true; } } else { - yb = *width - target_width; + yb = *width; a = axis_info.min_value; b = axis_info.default_value; @@ -322,10 +323,10 @@ hb_shape_justify (hb_font_t *font, features, num_features, shaper_list)) return false; - ya = buffer_width (buffer) - target_width; + ya = buffer_width (buffer); if (ya >= 0) { - *width = (float) ya + target_width; + *width = (float) ya; return true; } } @@ -344,26 +345,29 @@ hb_shape_justify (hb_font_t *font, shaper_list))) { failed = true; - return target_width; + return min_target_width; } - return buffer_width (buffer) - target_width; + printf ("%g\n", x); + return buffer_width (buffer); }; + double y = 0; double itp = solve_itp (f, a, b, epsilon, n0, k1, - ya, yb); + min_target_width, max_target_width, + ya, yb, y); hb_free (text_info); if (failed) return false; - *width = (float) (ya + yb) * 0.5f + target_width; *var_value = (float) itp; + *width = (float) y; return true; } diff --git a/src/hb-shape.h b/src/hb-shape.h index 821b6874b..8c2062c6a 100644 --- a/src/hb-shape.h +++ b/src/hb-shape.h @@ -59,7 +59,8 @@ hb_shape_justify (hb_font_t *font, const hb_feature_t *features, unsigned int num_features, const char * const *shaper_list, - float target_width, + float min_target_width, + float max_target_width, float *width, /* IN/OUT */ hb_tag_t *var_tag, /* OUT */ float *var_value /* OUT */); diff --git a/util/shape-options.hh b/util/shape-options.hh index 55a1f4c53..0d8977cd6 100644 --- a/util/shape-options.hh +++ b/util/shape-options.hh @@ -172,12 +172,14 @@ struct shape_options_t } else { - float target_width = width * (1 << SUBPIXEL_BITS); + float unit = (1 << SUBPIXEL_BITS); + float target_width = width * unit; float w = 0; hb_tag_t var_tag; float var_value; if (!hb_shape_justify (font, buffer, features, num_features, shapers, - target_width, &w, &var_tag, &var_value)) + target_width - unit * 0.5f, target_width + unit * 0.5f, + &w, &var_tag, &var_value)) { if (error) *error = "Shaping failed.";