From e39104ba1920a1bd2f6b4a56ace6cb66f7fcab6e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 1 Feb 2023 16:56:56 -0700 Subject: [PATCH] [font/util] Add emboldening API, --font-bold Needs documentation. --- src/hb-font.cc | 34 ++++++++++++++++++++++++++++++++-- src/hb-font.h | 6 ++++++ src/hb-font.hh | 12 ++++++++++++ src/hb-ft.cc | 4 +--- src/hb-ot-font.cc | 4 +--- util/font-options.hh | 25 ++++++++++++++++++++++++- 6 files changed, 76 insertions(+), 9 deletions(-) diff --git a/src/hb-font.cc b/src/hb-font.cc index 8a43ceb86..752b05594 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -1772,8 +1772,12 @@ DEFINE_NULL_INSTANCE (hb_font_t) = 1000, /* x_scale */ 1000, /* y_scale */ - 0., /* slant */ - 0., /* slant_xy; */ + 0.f, /* x_embolden */ + 0.f, /* y_embolden */ + 0, /* x_shift */ + 0, /* y_shift */ + 0.f, /* slant */ + 0.f, /* slant_xy; */ 1.f, /* x_multf */ 1.f, /* y_multf */ 1<<16, /* x_mult */ @@ -1895,6 +1899,8 @@ hb_font_create_sub_font (hb_font_t *parent) font->x_scale = parent->x_scale; font->y_scale = parent->y_scale; + font->x_embolden = parent->x_embolden; + font->y_embolden = parent->y_embolden; font->slant = parent->slant; font->x_ppem = parent->x_ppem; font->y_ppem = parent->y_ppem; @@ -2442,6 +2448,30 @@ hb_font_get_ptem (hb_font_t *font) return font->ptem; } +void +hb_font_set_synthetic_bold (hb_font_t *font, float x_embolden, float y_embolden) +{ + if (hb_object_is_immutable (font)) + return; + + if (font->x_embolden == x_embolden && + font->y_embolden == y_embolden) + return; + + font->serial++; + + font->x_embolden = x_embolden; + font->y_embolden = y_embolden; + font->mults_changed (); +} + +void +hb_font_get_synthetic_bold (hb_font_t *font, float *x_embolden, float *y_embolden) +{ + if (x_embolden) *x_embolden = font->x_embolden; + if (y_embolden) *y_embolden = font->y_embolden; +} + /** * hb_font_set_synthetic_slant: * @font: #hb_font_t to work upon diff --git a/src/hb-font.h b/src/hb-font.h index f187ddfaa..f90b6e20b 100644 --- a/src/hb-font.h +++ b/src/hb-font.h @@ -1131,6 +1131,12 @@ hb_font_set_ptem (hb_font_t *font, float ptem); HB_EXTERN float hb_font_get_ptem (hb_font_t *font); +HB_EXTERN void +hb_font_set_synthetic_bold (hb_font_t *font, float x_embolden, float y_embolden); + +HB_EXTERN void +hb_font_get_synthetic_bold (hb_font_t *font, float *x_embolden, float *y_embolden); + HB_EXTERN void hb_font_set_synthetic_slant (hb_font_t *font, float slant); diff --git a/src/hb-font.hh b/src/hb-font.hh index 292860a26..7a5b7eddc 100644 --- a/src/hb-font.hh +++ b/src/hb-font.hh @@ -113,8 +113,15 @@ struct hb_font_t int32_t x_scale; int32_t y_scale; + + float x_embolden; + float y_embolden; + int32_t x_shift; /* x_embolden, in scaled units. */ + int32_t y_shift; /* y_embolden, in scaled units. */ + float slant; float slant_xy; + float x_multf; float y_multf; int64_t x_mult; @@ -666,12 +673,17 @@ struct hb_font_t void mults_changed () { float upem = face->get_upem (); + x_multf = x_scale / upem; y_multf = y_scale / upem; bool x_neg = x_scale < 0; x_mult = (x_neg ? -((int64_t) -x_scale << 16) : ((int64_t) x_scale << 16)) / upem; bool y_neg = y_scale < 0; y_mult = (y_neg ? -((int64_t) -y_scale << 16) : ((int64_t) y_scale << 16)) / upem; + + x_shift = roundf (x_scale * x_embolden); + y_shift = roundf (y_scale * y_embolden); + slant_xy = y_scale ? slant * x_scale / y_scale : 0.f; data.fini (); diff --git a/src/hb-ft.cc b/src/hb-ft.cc index 3005828f0..35313569d 100644 --- a/src/hb-ft.cc +++ b/src/hb-ft.cc @@ -844,9 +844,7 @@ hb_ft_draw_glyph (hb_font_t *font, hb_draw_session_t draw_session (draw_funcs, draw_data, font->slant_xy); - hb_position_t xstr = font->x_scale / 20; - hb_position_t ystr = font->y_scale / 20; - FT_Outline_EmboldenXY (&ft_face->glyph->outline, xstr, ystr); + FT_Outline_EmboldenXY (&ft_face->glyph->outline, font->x_shift, font->y_shift); FT_Outline_Decompose (&ft_face->glyph->outline, &outline_funcs, &draw_session); diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 70e7c5e22..6b188ee9e 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -475,9 +475,7 @@ hb_ot_draw_glyph (hb_font_t *font, #endif {} - float xstr = font->x_scale / 20; - float ystr = font->y_scale / 20; - outline.embolden (xstr, ystr); + outline.embolden (font->x_shift, font->y_shift); outline.replay (draw_funcs, draw_data); } diff --git a/util/font-options.hh b/util/font-options.hh index efc5a1a8b..5b5de2265 100644 --- a/util/font-options.hh +++ b/util/font-options.hh @@ -63,6 +63,8 @@ struct font_options_t : face_options_t int x_ppem = 0; int y_ppem = 0; double ptem = 0.; + double x_embolden = 0.; + double y_embolden = 0.; double slant = 0.; unsigned int subpixel_bits = SUBPIXEL_BITS; mutable double font_size_x = DEFAULT_FONT_SIZE; @@ -101,6 +103,7 @@ font_options_t::post_parse (GError **error) hb_font_set_ppem (font, x_ppem, y_ppem); hb_font_set_ptem (font, ptem); + hb_font_set_synthetic_bold (font, (float) x_embolden, (float) y_embolden); hb_font_set_synthetic_slant (font, slant); int scale_x = (int) scalbnf (font_size_x, subpixel_bits); @@ -245,6 +248,24 @@ parse_font_ppem (const char *name G_GNUC_UNUSED, } } +static gboolean +parse_font_bold (const char *name G_GNUC_UNUSED, + const char *arg, + gpointer data, + GError **error G_GNUC_UNUSED) +{ + font_options_t *font_opts = (font_options_t *) data; + switch (sscanf (arg, "%lf%*[ ,]%lf", &font_opts->x_embolden, &font_opts->y_embolden)) { + case 1: font_opts->y_embolden = font_opts->x_embolden; HB_FALLTHROUGH; + case 2: return true; + default: + g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + "%s argument should be one or two space-separated numbers", + name); + return false; + } +} + void font_options_t::add_options (option_parser_t *parser) { @@ -286,7 +307,9 @@ font_options_t::add_options (option_parser_t *parser) G_OPTION_ARG_CALLBACK, (gpointer) &parse_font_ppem, "Set x,y pixels per EM (default: 0; disabled)", "1/2 integers"}, {"font-ptem", 0, font_size_flags, G_OPTION_ARG_DOUBLE, &this->ptem, "Set font point-size (default: 0; disabled)", "point-size"}, - {"font-slant", 0, 0, + {"font-bold", 0, font_size_flags, + G_OPTION_ARG_CALLBACK, (gpointer) &parse_font_bold, "Set synthetic bold (default: 0)", "1/2 numbers; eg. 0.05"}, + {"font-slant", 0, font_size_flags, G_OPTION_ARG_DOUBLE, &this->slant, "Set synthetic slant (default: 0)", "slant ratio; eg. 0.2"}, {"font-funcs", 0, 0, G_OPTION_ARG_STRING, &this->font_funcs, text, "impl"}, {"sub-font", 0, G_OPTION_FLAG_HIDDEN,