From 810f5d71c71ab59f4b1257e18b81551de49f3ee5 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 18 Dec 2021 15:12:26 -0700 Subject: [PATCH 01/11] [font] Add public API for slant Not hooked up internally to anything. New API: + hb_font_set_synthetic_slant() + hb_font_get_synthetic_slant() Part of fixing https://github.com/harfbuzz/harfbuzz/issues/3196 --- src/hb-font.cc | 41 ++++++++++++++++++++++++++++++++++++++++- src/hb-font.h | 6 ++++++ src/hb-font.hh | 1 + 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/hb-font.cc b/src/hb-font.cc index fa8da9639..dd1a31508 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -1477,6 +1477,7 @@ DEFINE_NULL_INSTANCE (hb_font_t) = 1000, /* x_scale */ 1000, /* y_scale */ + 0., /* slant */ 1<<16, /* x_mult */ 1<<16, /* y_mult */ @@ -1578,6 +1579,7 @@ hb_font_create_sub_font (hb_font_t *parent) font->x_scale = parent->x_scale; font->y_scale = parent->y_scale; + font->slant = parent->slant; font->mults_changed (); font->x_ppem = parent->x_ppem; font->y_ppem = parent->y_ppem; @@ -2015,7 +2017,7 @@ hb_font_set_ptem (hb_font_t *font, * * Return value: Point size. A value of zero means "not set." * - * Since: 0.9.2 + * Since: 1.6.0 **/ float hb_font_get_ptem (hb_font_t *font) @@ -2023,6 +2025,43 @@ hb_font_get_ptem (hb_font_t *font) return font->ptem; } +/** + * hb_font_set_synthetic_slant: + * @font: #hb_font_t to work upon + * @ptem: font size in points. + * + * Sets the XXX "point size" of a font. By default is zero. + * + * Note: XXX There are 72 points in an inch. + * + * Since: REPLACEME + **/ +HB_EXTERN void +hb_font_set_synthetic_slant (hb_font_t *font, float slant) +{ + if (hb_object_is_immutable (font)) + return; + + font->slant = slant; + font->mults_changed (); +} + +/** + * hb_font_get_synthetic_slant: + * @font: #hb_font_t to work upon + * + * Fetches the "point size" of a font. + * + * Return value: XXX Point size. By default is zero. + * + * Since: REPLACEME + **/ +HB_EXTERN float +hb_font_get_synthetic_slant (hb_font_t *font) +{ + return font->slant; +} + #ifndef HB_NO_VAR /* * Variations diff --git a/src/hb-font.h b/src/hb-font.h index 15dc12652..ff2e7df54 100644 --- a/src/hb-font.h +++ b/src/hb-font.h @@ -1023,6 +1023,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_slant (hb_font_t *font, float slant); + +HB_EXTERN float +hb_font_get_synthetic_slant (hb_font_t *font); + HB_EXTERN void hb_font_set_variations (hb_font_t *font, const hb_variation_t *variations, diff --git a/src/hb-font.hh b/src/hb-font.hh index 1b7f445e8..248d85deb 100644 --- a/src/hb-font.hh +++ b/src/hb-font.hh @@ -109,6 +109,7 @@ struct hb_font_t int32_t x_scale; int32_t y_scale; + float slant; int64_t x_mult; int64_t y_mult; From ff697debd8e55d8858a2f199ae06f7a9f33a5991 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 19 Dec 2021 07:25:37 -0700 Subject: [PATCH 02/11] [GPOS] Apply font synthetic slant Part of fixing https://github.com/harfbuzz/harfbuzz/issues/3196 --- src/hb-font.cc | 1 + src/hb-font.hh | 2 ++ src/hb-ot-layout-gpos-table.hh | 11 +++++++++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/hb-font.cc b/src/hb-font.cc index dd1a31508..1c6a41011 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -1478,6 +1478,7 @@ DEFINE_NULL_INSTANCE (hb_font_t) = 1000, /* x_scale */ 1000, /* y_scale */ 0., /* slant */ + 0., /* slant_xy; */ 1<<16, /* x_mult */ 1<<16, /* y_mult */ diff --git a/src/hb-font.hh b/src/hb-font.hh index 248d85deb..0d73589e8 100644 --- a/src/hb-font.hh +++ b/src/hb-font.hh @@ -110,6 +110,7 @@ struct hb_font_t int32_t x_scale; int32_t y_scale; float slant; + float slant_xy; int64_t x_mult; int64_t y_mult; @@ -618,6 +619,7 @@ struct hb_font_t signed upem = face->get_upem (); x_mult = ((int64_t) x_scale << 16) / upem; y_mult = ((int64_t) y_scale << 16) / upem; + slant_xy = y_scale ? slant * x_scale / y_scale : 0.f; } hb_position_t em_mult (int16_t v, int64_t mult) diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index 6db3e0894..bda6f02b8 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -2951,7 +2951,7 @@ GPOS::position_finish_advances (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer H } void -GPOS::position_finish_offsets (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) +GPOS::position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer) { _hb_buffer_assert_gsubgpos_vars (buffer); @@ -2961,8 +2961,15 @@ GPOS::position_finish_offsets (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) /* Handle attachments */ if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT) - for (unsigned int i = 0; i < len; i++) + for (unsigned i = 0; i < len; i++) propagate_attachment_offsets (pos, len, i, direction); + + if (unlikely (font->slant)) + { + for (unsigned i = 0; i < len; i++) + if (unlikely (pos[i].y_offset)) + pos[i].x_offset += _hb_roundf (font->slant_xy * pos[i].y_offset); + } } From 602bd39680e6c337309516d6b5086834a35a7609 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 19 Dec 2021 21:40:25 -0800 Subject: [PATCH 03/11] [style] Adjust font slant angle for synthetic slant value Part of https://github.com/harfbuzz/harfbuzz/pull/3338 --- src/hb-style.cc | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/hb-style.cc b/src/hb-style.cc index f1b44cea5..c0c5c4832 100644 --- a/src/hb-style.cc +++ b/src/hb-style.cc @@ -48,13 +48,12 @@ _hb_angle_to_ratio (float a) { return tanf (a * float (M_PI / 180.)); } -#if 0 + static inline float _hb_ratio_to_angle (float r) { return atanf (r) * float (180. / M_PI); } -#endif /** * hb_style_get_value: @@ -73,7 +72,8 @@ float hb_style_get_value (hb_font_t *font, hb_style_tag_t style_tag) { if (unlikely (style_tag == HB_STYLE_TAG_SLANT_RATIO)) - return _hb_angle_to_ratio (hb_style_get_value (font, HB_STYLE_TAG_SLANT_ANGLE)); + return _hb_angle_to_ratio (hb_style_get_value (font, HB_STYLE_TAG_SLANT_ANGLE)) + + font->slant; hb_face_t *face = font->face; @@ -109,7 +109,14 @@ hb_style_get_value (hb_font_t *font, hb_style_tag_t style_tag) : 12.f; } case HB_STYLE_TAG_SLANT_ANGLE: - return face->table.post->table->italicAngle.to_float (); + { + float angle = face->table.post->table->italicAngle.to_float (); + + if (font->slant) + angle = _hb_ratio_to_angle (font->slant + _hb_angle_to_ratio (angle)); + + return angle; + } case HB_STYLE_TAG_WIDTH: return face->table.OS2->has_data () ? face->table.OS2->get_width () From fc329f665fab56c2983ababf2ebc71088b2ecfcc Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 2 Jan 2022 10:41:41 -0700 Subject: [PATCH 04/11] [metrics] Scale up horizontal caret rise/run Eg. if rise/run are 1/0, we now return upem/0. This is equivalent. Part of https://github.com/harfbuzz/harfbuzz/pull/3338 --- src/hb-ot-metrics.cc | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/hb-ot-metrics.cc b/src/hb-ot-metrics.cc index dbd4a1ffb..4147ebe66 100644 --- a/src/hb-ot-metrics.cc +++ b/src/hb-ot-metrics.cc @@ -160,9 +160,20 @@ hb_ot_metrics_get_position (hb_font_t *font, (position && (*position = font->em_scalef_y (face->table.TABLE->ATTR + GET_VAR)), true)) case HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_ASCENT: return GET_METRIC_Y (OS2, usWinAscent); case HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_DESCENT: return GET_METRIC_Y (OS2, usWinDescent); - case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE: return GET_METRIC_Y (hhea, caretSlopeRise); - case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RUN: return GET_METRIC_X (hhea, caretSlopeRun); + + case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE: + case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RUN: + { + unsigned rise = face->table.hhea->caretSlopeRise; + unsigned upem = face->get_upem (); + unsigned mult = rise < upem ? upem / rise : 1; + if (metrics_tag == HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE) + return mult * GET_METRIC_Y (hhea, caretSlopeRise); + else + return mult * GET_METRIC_X (hhea, caretSlopeRun); + } case HB_OT_METRICS_TAG_HORIZONTAL_CARET_OFFSET: return GET_METRIC_X (hhea, caretOffset); + #ifndef HB_NO_VERTICAL case HB_OT_METRICS_TAG_VERTICAL_CARET_RISE: return GET_METRIC_X (vhea, caretSlopeRise); case HB_OT_METRICS_TAG_VERTICAL_CARET_RUN: return GET_METRIC_Y (vhea, caretSlopeRun); From fa008a021fbd3c432499ac9316fa75a7f5a4ea02 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 2 Jan 2022 10:46:38 -0700 Subject: [PATCH 05/11] [metrics] Implement synthetic slant for caret slope Part of https://github.com/harfbuzz/harfbuzz/pull/3338 --- src/hb-ot-metrics.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/hb-ot-metrics.cc b/src/hb-ot-metrics.cc index 4147ebe66..743a7f687 100644 --- a/src/hb-ot-metrics.cc +++ b/src/hb-ot-metrics.cc @@ -167,10 +167,18 @@ hb_ot_metrics_get_position (hb_font_t *font, unsigned rise = face->table.hhea->caretSlopeRise; unsigned upem = face->get_upem (); unsigned mult = rise < upem ? upem / rise : 1; + if (metrics_tag == HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE) return mult * GET_METRIC_Y (hhea, caretSlopeRise); else - return mult * GET_METRIC_X (hhea, caretSlopeRun); + { + unsigned run = mult * GET_METRIC_X (hhea, caretSlopeRun); + + if (font->slant) + run += _hb_roundf (mult * GET_METRIC_Y (hhea, caretSlopeRise) * font->slant); + + return run; + } } case HB_OT_METRICS_TAG_HORIZONTAL_CARET_OFFSET: return GET_METRIC_X (hhea, caretOffset); From 45c2b6e384e3359a54f40e4b02df9fffe27b0def Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 2 Jan 2022 10:55:11 -0700 Subject: [PATCH 06/11] [metrics] Harden math --- src/hb-ot-metrics.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-metrics.cc b/src/hb-ot-metrics.cc index 743a7f687..f0c437a3c 100644 --- a/src/hb-ot-metrics.cc +++ b/src/hb-ot-metrics.cc @@ -166,7 +166,7 @@ hb_ot_metrics_get_position (hb_font_t *font, { unsigned rise = face->table.hhea->caretSlopeRise; unsigned upem = face->get_upem (); - unsigned mult = rise < upem ? upem / rise : 1; + unsigned mult = (rise && rise < upem) ? hb_min (upem / rise, 256u) : 1u; if (metrics_tag == HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE) return mult * GET_METRIC_Y (hhea, caretSlopeRise); From f1ba1f940f407efd192cb2d6bd4b7eee20aedf96 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 2 Jan 2022 10:58:25 -0700 Subject: [PATCH 07/11] [metrics] Only scale caret rise/run if font is slanted --- src/hb-ot-metrics.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-metrics.cc b/src/hb-ot-metrics.cc index f0c437a3c..7ebdd1f09 100644 --- a/src/hb-ot-metrics.cc +++ b/src/hb-ot-metrics.cc @@ -166,7 +166,7 @@ hb_ot_metrics_get_position (hb_font_t *font, { unsigned rise = face->table.hhea->caretSlopeRise; unsigned upem = face->get_upem (); - unsigned mult = (rise && rise < upem) ? hb_min (upem / rise, 256u) : 1u; + unsigned mult = (font->slant && rise && rise < upem) ? hb_min (upem / rise, 256u) : 1u; if (metrics_tag == HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE) return mult * GET_METRIC_Y (hhea, caretSlopeRise); From f7d49d9c2b9899f9caeeff766714631918129d2c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 2 Jan 2022 11:16:33 -0700 Subject: [PATCH 08/11] [metrics] Simplify --- src/hb-ot-metrics.cc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/hb-ot-metrics.cc b/src/hb-ot-metrics.cc index 7ebdd1f09..b7153151d 100644 --- a/src/hb-ot-metrics.cc +++ b/src/hb-ot-metrics.cc @@ -164,9 +164,14 @@ hb_ot_metrics_get_position (hb_font_t *font, case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE: case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RUN: { - unsigned rise = face->table.hhea->caretSlopeRise; - unsigned upem = face->get_upem (); - unsigned mult = (font->slant && rise && rise < upem) ? hb_min (upem / rise, 256u) : 1u; + unsigned mult = 1u; + + if (font->slant) + { + unsigned rise = face->table.hhea->caretSlopeRise; + unsigned upem = face->get_upem (); + mult = (rise && rise < upem) ? hb_min (upem / rise, 256u) : 1u; + } if (metrics_tag == HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE) return mult * GET_METRIC_Y (hhea, caretSlopeRise); From 4ab94443bbe80a354daa2d94e496c13f096501ad Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 2 Jan 2022 11:26:45 -0700 Subject: [PATCH 09/11] [metrics] Ouch. Fix slant code --- src/hb-ot-metrics.cc | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/hb-ot-metrics.cc b/src/hb-ot-metrics.cc index b7153151d..bf4bacd75 100644 --- a/src/hb-ot-metrics.cc +++ b/src/hb-ot-metrics.cc @@ -174,15 +174,32 @@ hb_ot_metrics_get_position (hb_font_t *font, } if (metrics_tag == HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE) - return mult * GET_METRIC_Y (hhea, caretSlopeRise); + { + bool ret = GET_METRIC_Y (hhea, caretSlopeRise); + + if (position) + *position *= mult; + + return ret; + } else { - unsigned run = mult * GET_METRIC_X (hhea, caretSlopeRun); + hb_position_t rise = 0; - if (font->slant) - run += _hb_roundf (mult * GET_METRIC_Y (hhea, caretSlopeRise) * font->slant); + if (font->slant && position && GET_METRIC_Y (hhea, caretSlopeRise)) + rise = *position; - return run; + bool ret = GET_METRIC_X (hhea, caretSlopeRun); + + if (position) + { + *position *= mult; + + if (font->slant) + *position += _hb_roundf (mult * rise * font->slant); + } + + return ret; } } case HB_OT_METRICS_TAG_HORIZONTAL_CARET_OFFSET: return GET_METRIC_X (hhea, caretOffset); From a7751277e9e8982093928e762ac9eecc42820444 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 2 Jan 2022 11:50:02 -0700 Subject: [PATCH 10/11] [docs] Add hb_font_[gs]et_synthetic_slant() --- docs/harfbuzz-sections.txt | 2 ++ src/hb-font.cc | 14 ++++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index f2c75930d..a6ae470f2 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -329,6 +329,7 @@ hb_font_get_parent hb_font_get_ppem hb_font_get_ptem hb_font_get_scale +hb_font_get_synthetic_slant hb_font_get_user_data hb_font_get_variation_glyph hb_font_get_variation_glyph_func_t @@ -345,6 +346,7 @@ hb_font_set_parent hb_font_set_ppem hb_font_set_ptem hb_font_set_scale +hb_font_set_synthetic_slant hb_font_set_user_data hb_font_set_variations hb_font_set_var_coords_design diff --git a/src/hb-font.cc b/src/hb-font.cc index 1c6a41011..7e24d0dfc 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -2031,9 +2031,15 @@ hb_font_get_ptem (hb_font_t *font) * @font: #hb_font_t to work upon * @ptem: font size in points. * - * Sets the XXX "point size" of a font. By default is zero. + * Sets the "synthetic slant" of a font. By default is zero. + * Synthetic slant is the graphical skew that the renderer + * applies to the font at rendering time. * - * Note: XXX There are 72 points in an inch. + * HarfBuzz needs to know this value to adjust shaping results, + * metrics, and style values to match the slanted rendering. + * + * Note: The slant value is a ratio. For example, a + * 20% slant would be represented as a 0.2 value. * * Since: REPLACEME **/ @@ -2051,9 +2057,9 @@ hb_font_set_synthetic_slant (hb_font_t *font, float slant) * hb_font_get_synthetic_slant: * @font: #hb_font_t to work upon * - * Fetches the "point size" of a font. + * Fetches the "synthetic slant" of a font. * - * Return value: XXX Point size. By default is zero. + * Return value: Synthetic slant. By default is zero. * * Since: REPLACEME **/ From 3fc2e654c0eca9566b184fd64c682114f99b2093 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 2 Jan 2022 11:56:45 -0700 Subject: [PATCH 11/11] [metrics] Fix slant calc --- src/hb-ot-metrics.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-metrics.cc b/src/hb-ot-metrics.cc index bf4bacd75..103808cf9 100644 --- a/src/hb-ot-metrics.cc +++ b/src/hb-ot-metrics.cc @@ -196,7 +196,7 @@ hb_ot_metrics_get_position (hb_font_t *font, *position *= mult; if (font->slant) - *position += _hb_roundf (mult * rise * font->slant); + *position += _hb_roundf (mult * font->slant_xy * rise); } return ret;