From bbb9d6d436b7fb5aba771c63378aa4daa231b8c5 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 28 Feb 2023 12:07:48 -0700 Subject: [PATCH] [font] Add hb_font_set_variation() --- docs/harfbuzz-sections.txt | 1 + src/hb-font.cc | 64 ++++++++++++++++++++++++++++++++++++++ src/hb-font.h | 5 +++ 3 files changed, 70 insertions(+) diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index 885a71a91..b475bbae3 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -421,6 +421,7 @@ hb_font_set_synthetic_bold hb_font_set_synthetic_slant hb_font_get_synthetic_slant hb_font_set_variations +hb_font_set_variation HB_FONT_NO_VAR_NAMED_INSTANCE hb_font_set_var_named_instance hb_font_get_var_named_instance diff --git a/src/hb-font.cc b/src/hb-font.cc index 386886310..dcd852b03 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -2649,6 +2649,70 @@ hb_font_set_variations (hb_font_t *font, _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length); } +/** + * hb_font_set_variation: + * @font: #hb_font_t to work upon + * @tag: The #hb_tag_t tag of the variation-axis name + * @value: The value of the variation axis + * + * Change the value of one variation axis on the font. + * + * Note: This function is expensive to be called repeatedly. + * If you want to set multipl variation axes at the same time, + * use hb_font_set_variations() instead. + * + * XSince: REPLACEME + */ +void +hb_font_set_variation (hb_font_t *font, + hb_tag_t tag, + float value) +{ + if (hb_object_is_immutable (font)) + return; + + font->serial_coords = ++font->serial; + + // TODO Share some of this code with set_variations() + + const OT::fvar &fvar = *font->face->table.fvar; + auto axes = fvar.get_axes (); + const unsigned coords_length = axes.length; + + int *normalized = coords_length ? (int *) hb_calloc (coords_length, sizeof (int)) : nullptr; + float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr; + + if (unlikely (coords_length && !(normalized && design_coords))) + { + hb_free (normalized); + hb_free (design_coords); + return; + } + + /* Initialize design coords. */ + for (unsigned int i = 0; i < coords_length; i++) + design_coords[i] = axes[i].get_default (); + if (font->instance_index != HB_FONT_NO_VAR_NAMED_INSTANCE) + { + unsigned count = coords_length; + /* This may fail if index is out-of-range; + * That's why we initialize design_coords from fvar above + * unconditionally. */ + hb_ot_var_named_instance_get_design_coords (font->face, font->instance_index, + &count, design_coords); + } + + for (unsigned axis_index = 0; axis_index < coords_length; axis_index++) + if (axes[axis_index].axisTag == tag) + design_coords[axis_index] = value; + + font->face->table.avar->map_coords (normalized, coords_length); + + hb_ot_var_normalize_coords (font->face, coords_length, design_coords, normalized); + _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length); + +} + /** * hb_font_set_var_coords_design: * @font: #hb_font_t to work upon diff --git a/src/hb-font.h b/src/hb-font.h index 69457da57..f3b589bd0 100644 --- a/src/hb-font.h +++ b/src/hb-font.h @@ -1150,6 +1150,11 @@ hb_font_set_variations (hb_font_t *font, const hb_variation_t *variations, unsigned int variations_length); +HB_EXTERN void +hb_font_set_variation (hb_font_t *font, + hb_tag_t tag, + float value); + HB_EXTERN void hb_font_set_var_coords_design (hb_font_t *font, const float *coords,