[font/util] Add emboldening API, --font-bold

Needs documentation.
This commit is contained in:
Behdad Esfahbod 2023-02-01 16:56:56 -07:00
parent 4247b78e31
commit e39104ba19
6 changed files with 76 additions and 9 deletions

View File

@ -1772,8 +1772,12 @@ DEFINE_NULL_INSTANCE (hb_font_t) =
1000, /* x_scale */ 1000, /* x_scale */
1000, /* y_scale */ 1000, /* y_scale */
0., /* slant */ 0.f, /* x_embolden */
0., /* slant_xy; */ 0.f, /* y_embolden */
0, /* x_shift */
0, /* y_shift */
0.f, /* slant */
0.f, /* slant_xy; */
1.f, /* x_multf */ 1.f, /* x_multf */
1.f, /* y_multf */ 1.f, /* y_multf */
1<<16, /* x_mult */ 1<<16, /* x_mult */
@ -1895,6 +1899,8 @@ hb_font_create_sub_font (hb_font_t *parent)
font->x_scale = parent->x_scale; font->x_scale = parent->x_scale;
font->y_scale = parent->y_scale; font->y_scale = parent->y_scale;
font->x_embolden = parent->x_embolden;
font->y_embolden = parent->y_embolden;
font->slant = parent->slant; font->slant = parent->slant;
font->x_ppem = parent->x_ppem; font->x_ppem = parent->x_ppem;
font->y_ppem = parent->y_ppem; font->y_ppem = parent->y_ppem;
@ -2442,6 +2448,30 @@ hb_font_get_ptem (hb_font_t *font)
return font->ptem; 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: * hb_font_set_synthetic_slant:
* @font: #hb_font_t to work upon * @font: #hb_font_t to work upon

View File

@ -1131,6 +1131,12 @@ hb_font_set_ptem (hb_font_t *font, float ptem);
HB_EXTERN float HB_EXTERN float
hb_font_get_ptem (hb_font_t *font); 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_EXTERN void
hb_font_set_synthetic_slant (hb_font_t *font, float slant); hb_font_set_synthetic_slant (hb_font_t *font, float slant);

View File

@ -113,8 +113,15 @@ struct hb_font_t
int32_t x_scale; int32_t x_scale;
int32_t y_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;
float slant_xy; float slant_xy;
float x_multf; float x_multf;
float y_multf; float y_multf;
int64_t x_mult; int64_t x_mult;
@ -666,12 +673,17 @@ struct hb_font_t
void mults_changed () void mults_changed ()
{ {
float upem = face->get_upem (); float upem = face->get_upem ();
x_multf = x_scale / upem; x_multf = x_scale / upem;
y_multf = y_scale / upem; y_multf = y_scale / upem;
bool x_neg = x_scale < 0; bool x_neg = x_scale < 0;
x_mult = (x_neg ? -((int64_t) -x_scale << 16) : ((int64_t) x_scale << 16)) / upem; x_mult = (x_neg ? -((int64_t) -x_scale << 16) : ((int64_t) x_scale << 16)) / upem;
bool y_neg = y_scale < 0; bool y_neg = y_scale < 0;
y_mult = (y_neg ? -((int64_t) -y_scale << 16) : ((int64_t) y_scale << 16)) / upem; 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; slant_xy = y_scale ? slant * x_scale / y_scale : 0.f;
data.fini (); data.fini ();

View File

@ -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_draw_session_t draw_session (draw_funcs, draw_data, font->slant_xy);
hb_position_t xstr = font->x_scale / 20; FT_Outline_EmboldenXY (&ft_face->glyph->outline, font->x_shift, font->y_shift);
hb_position_t ystr = font->y_scale / 20;
FT_Outline_EmboldenXY (&ft_face->glyph->outline, xstr, ystr);
FT_Outline_Decompose (&ft_face->glyph->outline, FT_Outline_Decompose (&ft_face->glyph->outline,
&outline_funcs, &outline_funcs,
&draw_session); &draw_session);

View File

@ -475,9 +475,7 @@ hb_ot_draw_glyph (hb_font_t *font,
#endif #endif
{} {}
float xstr = font->x_scale / 20; outline.embolden (font->x_shift, font->y_shift);
float ystr = font->y_scale / 20;
outline.embolden (xstr, ystr);
outline.replay (draw_funcs, draw_data); outline.replay (draw_funcs, draw_data);
} }

View File

@ -63,6 +63,8 @@ struct font_options_t : face_options_t
int x_ppem = 0; int x_ppem = 0;
int y_ppem = 0; int y_ppem = 0;
double ptem = 0.; double ptem = 0.;
double x_embolden = 0.;
double y_embolden = 0.;
double slant = 0.; double slant = 0.;
unsigned int subpixel_bits = SUBPIXEL_BITS; unsigned int subpixel_bits = SUBPIXEL_BITS;
mutable double font_size_x = DEFAULT_FONT_SIZE; 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_ppem (font, x_ppem, y_ppem);
hb_font_set_ptem (font, ptem); 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); hb_font_set_synthetic_slant (font, slant);
int scale_x = (int) scalbnf (font_size_x, subpixel_bits); 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 void
font_options_t::add_options (option_parser_t *parser) 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"}, 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, {"font-ptem", 0, font_size_flags,
G_OPTION_ARG_DOUBLE, &this->ptem, "Set font point-size (default: 0; disabled)", "point-size"}, 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"}, 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"}, {"font-funcs", 0, 0, G_OPTION_ARG_STRING, &this->font_funcs, text, "impl"},
{"sub-font", 0, G_OPTION_FLAG_HIDDEN, {"sub-font", 0, G_OPTION_FLAG_HIDDEN,