diff --git a/src/hb-shape.cc b/src/hb-shape.cc index 7b5bf2c5e..ab4ea88d7 100644 --- a/src/hb-shape.cc +++ b/src/hb-shape.cc @@ -196,4 +196,88 @@ hb_shape (hb_font_t *font, } +static float +buffer_width (hb_buffer_t *buffer) +{ + float w = 0; + auto *pos = buffer->pos; + unsigned count = buffer->len; + for (unsigned i = 0; i < count; i++) + w += pos[i].x_advance; + return w; +} + +hb_bool_t +hb_shape_justify (hb_font_t *font, + hb_buffer_t *buffer, + const hb_feature_t *features, + unsigned int num_features, + const char * const *shaper_list, + float target_width, + float *width) +{ + // TODO vertical + // TODO buffer context + + if (target_width == *width) + return hb_shape_full (font, buffer, + features, num_features, + shaper_list); + + hb_face_t *face = font->face; + + hb_ot_var_axis_info_t axis_info; + if (!hb_ot_var_find_axis_info (face, HB_TAG ('j','s','t','f'), &axis_info) && + !hb_ot_var_find_axis_info (face, HB_TAG ('w','d','t','h'), &axis_info)) + { + if (hb_shape_full (font, buffer, + features, num_features, + shaper_list)) + { + *width = buffer_width (buffer); + return true; + } + else + return false; + } + + auto *text_info = (hb_glyph_info_t *) hb_malloc (buffer->len * sizeof (buffer->info[0])); + if (unlikely (!text_info)) + return false; + memcpy (text_info, buffer->info, buffer->len * sizeof (buffer->info[0])); + + if (!*width) + { + if (hb_shape_full (font, buffer, + features, num_features, + shaper_list)) + return false; + *width = buffer_width (buffer); + } + + if (target_width == *width) + return true; + + hb_font_t *sub_font = hb_font_create_sub_font (font); + + float a, b, ya, yb; + + const float epsilon; + const unsigned n0 = 1; + const k1 = 0.2 / (b - a); + + double var = solve_itp (func_t f, + double a, double b, + double epsilon, + unsigned n0, + double k1, + double &ya, double yb); + + hb_font_destroy (sub_font); + hb_free (text_info); + + return false; +} + + #endif diff --git a/src/hb-shape.h b/src/hb-shape.h index 922f8c011..8861ed861 100644 --- a/src/hb-shape.h +++ b/src/hb-shape.h @@ -53,6 +53,15 @@ hb_shape_full (hb_font_t *font, unsigned int num_features, const char * const *shaper_list); +HB_EXTERN hb_bool_t +hb_shape_justify (hb_font_t *font, + hb_buffer_t *buffer, + const hb_feature_t *features, + unsigned int num_features, + const char * const *shaper_list, + float target_width, + float *width); + HB_EXTERN const char ** hb_shape_list_shapers (void);