[justify] Add min/max target_width

Speeds up solving when some slack available.
This commit is contained in:
Behdad Esfahbod 2023-03-01 10:44:57 -07:00
parent 6e483c4061
commit b937edfb14
4 changed files with 29 additions and 20 deletions

View File

@ -1357,7 +1357,8 @@ double solve_itp (func_t f,
double epsilon, double epsilon,
unsigned n0, unsigned n0,
double k1, 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 n1_2 = (unsigned) (hb_max (ceil (log2 ((b - a) / epsilon)) - 1.0, 0.0));
unsigned nmax = n0 + n1_2; 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 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 xitp = fabs (xt - x1_2) <= r ? xt : x1_2 - r * sigma_sign;
double yitp = f (xitp); double yitp = f (xitp);
if (yitp > 0.0) if (yitp > max_y)
{ {
b = xitp; b = xitp;
yb = yitp; yb = yitp;
} }
else if (yitp < 0.0) else if (yitp < min_y)
{ {
a = xitp; a = xitp;
ya = yitp; ya = yitp;
} }
else else
{ {
y = yitp;
return xitp; return xitp;
} }
scaled_epsilon *= 0.5; scaled_epsilon *= 0.5;

View File

@ -228,14 +228,15 @@ hb_shape_justify (hb_font_t *font,
const hb_feature_t *features, const hb_feature_t *features,
unsigned int num_features, unsigned int num_features,
const char * const *shaper_list, const char * const *shaper_list,
float target_width, float min_target_width,
float max_target_width,
float *width, /* IN/OUT */ float *width, /* IN/OUT */
hb_tag_t *var_tag, /* OUT */ hb_tag_t *var_tag, /* OUT */
float *var_value /* OUT */) float *var_value /* OUT */)
{ {
// TODO Negative font scales? // TODO Negative font scales?
if (target_width == *width) if (min_target_width <= *width && *width <= max_target_width)
return hb_shape_full (font, buffer, return hb_shape_full (font, buffer,
features, num_features, features, num_features,
shaper_list); shaper_list);
@ -287,13 +288,13 @@ hb_shape_justify (hb_font_t *font,
*width = buffer_width (buffer); *width = buffer_width (buffer);
} }
if (target_width == *width) if (min_target_width <= *width && *width <= max_target_width)
return true; return true;
double a, b, ya, yb; 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; a = axis_info.default_value;
b = axis_info.max_value; b = axis_info.max_value;
@ -303,16 +304,16 @@ hb_shape_justify (hb_font_t *font,
features, num_features, features, num_features,
shaper_list)) shaper_list))
return false; return false;
yb = buffer_width (buffer) - target_width; yb = buffer_width (buffer);
if (yb <= 0) if (yb <= 0)
{ {
*width = (float) yb + target_width; *width = (float) yb;
return true; return true;
} }
} }
else else
{ {
yb = *width - target_width; yb = *width;
a = axis_info.min_value; a = axis_info.min_value;
b = axis_info.default_value; b = axis_info.default_value;
@ -322,10 +323,10 @@ hb_shape_justify (hb_font_t *font,
features, num_features, features, num_features,
shaper_list)) shaper_list))
return false; return false;
ya = buffer_width (buffer) - target_width; ya = buffer_width (buffer);
if (ya >= 0) if (ya >= 0)
{ {
*width = (float) ya + target_width; *width = (float) ya;
return true; return true;
} }
} }
@ -344,26 +345,29 @@ hb_shape_justify (hb_font_t *font,
shaper_list))) shaper_list)))
{ {
failed = true; 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, double itp = solve_itp (f,
a, b, a, b,
epsilon, epsilon,
n0, n0,
k1, k1,
ya, yb); min_target_width, max_target_width,
ya, yb, y);
hb_free (text_info); hb_free (text_info);
if (failed) if (failed)
return false; return false;
*width = (float) (ya + yb) * 0.5f + target_width;
*var_value = (float) itp; *var_value = (float) itp;
*width = (float) y;
return true; return true;
} }

View File

@ -59,7 +59,8 @@ hb_shape_justify (hb_font_t *font,
const hb_feature_t *features, const hb_feature_t *features,
unsigned int num_features, unsigned int num_features,
const char * const *shaper_list, const char * const *shaper_list,
float target_width, float min_target_width,
float max_target_width,
float *width, /* IN/OUT */ float *width, /* IN/OUT */
hb_tag_t *var_tag, /* OUT */ hb_tag_t *var_tag, /* OUT */
float *var_value /* OUT */); float *var_value /* OUT */);

View File

@ -172,12 +172,14 @@ struct shape_options_t
} }
else else
{ {
float target_width = width * (1 << SUBPIXEL_BITS); float unit = (1 << SUBPIXEL_BITS);
float target_width = width * unit;
float w = 0; float w = 0;
hb_tag_t var_tag; hb_tag_t var_tag;
float var_value; float var_value;
if (!hb_shape_justify (font, buffer, features, num_features, shapers, 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) if (error)
*error = "Shaping failed."; *error = "Shaping failed.";