[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,
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;

View File

@ -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;
}

View File

@ -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 */);

View File

@ -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.";