docs/harfbuzz-sections.txt | 10 ++- src/Makefile.sources | 1 src/hb-font.cc | 25 ++----- src/hb-font.h | 2 src/hb-ft.cc | 2 src/hb-ot-math.cc | 2 src/hb-ot-var-avar-table.hh | 143 ++++++++++++++++++++++++++++++++++++++++++++ src/hb-ot-var.cc | 64 ++++++++++++++++--- src/hb-ot-var.h | 22 +++++- util/helper-cairo.cc | 14 ++-- util/options.cc | 53 ++++------------ 11 files changed, 257 insertions(+), 81 deletions(-)
New commits: commit 7a860f656e4aec45c45e0f5fb28c49a91dc5eef2 Author: Behdad Esfahbod <beh...@behdad.org> Date: Sun Jan 22 19:52:09 2017 -0800 [var] Add macros for standard axes diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index fcf4e52..3011ee9 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -442,6 +442,11 @@ Xhb_ot_layout_lookup_substitute <FILE>hb-ot-var</FILE> HB_OT_TAG_avar HB_OT_TAG_fvar +HB_OT_TAG_VAR_AXIS_ITALIC +HB_OT_TAG_VAR_AXIS_OPTICAL_SIZE +HB_OT_TAG_VAR_AXIS_SLANT +HB_OT_TAG_VAR_AXIS_WEIGHT +HB_OT_TAG_VAR_AXIS_WIDTH HB_OT_VAR_NO_AXIS_INDEX hb_ot_var_axis_t hb_ot_var_has_data @@ -584,6 +589,8 @@ hb_unicode_script_func_t <FILE>hb-uniscribe</FILE> hb_uniscribe_font_get_hfont hb_uniscribe_font_get_logfontw +<SUBSECTION Private> +hb_directwrite_shape_experimental_width </SECTION> <SECTION> diff --git a/src/hb-ot-var.h b/src/hb-ot-var.h index bce7c7a..ea69aa5 100644 --- a/src/hb-ot-var.h +++ b/src/hb-ot-var.h @@ -39,6 +39,12 @@ HB_BEGIN_DECLS #define HB_OT_TAG_fvar HB_TAG('f','v','a','r') #define HB_OT_TAG_avar HB_TAG('a','v','a','r') +#define HB_OT_TAG_VAR_AXIS_ITALIC HB_TAG('i','t','a','l') +#define HB_OT_TAG_VAR_AXIS_OPTICAL_SIZE HB_TAG('o','p','s','z') +#define HB_OT_TAG_VAR_AXIS_SLANT HB_TAG('s','l','n','t') +#define HB_OT_TAG_VAR_AXIS_WIDTH HB_TAG('w','d','t','h') +#define HB_OT_TAG_VAR_AXIS_WEIGHT HB_TAG('w','g','h','t') + /* * fvar / avar commit a484e237b11650d00092329855d33dd2f67980e4 Author: Behdad Esfahbod <beh...@behdad.org> Date: Sun Jan 22 19:41:33 2017 -0800 [var] Implement 'avar' table mapping Untested! diff --git a/src/hb-ot-math.cc b/src/hb-ot-math.cc index eb08bad..2d7e679 100644 --- a/src/hb-ot-math.cc +++ b/src/hb-ot-math.cc @@ -34,9 +34,7 @@ static inline const OT::MATH& _get_math (hb_face_t *face) { if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::MATH); - hb_ot_layout_t * layout = hb_ot_layout_from_face (face); - return *(layout->math.get ()); } diff --git a/src/hb-ot-var-avar-table.hh b/src/hb-ot-var-avar-table.hh index a041934..743d587 100644 --- a/src/hb-ot-var-avar-table.hh +++ b/src/hb-ot-var-avar-table.hh @@ -50,7 +50,39 @@ struct AxisValueMap DEFINE_SIZE_STATIC (4); }; -typedef ArrayOf<AxisValueMap> SegmentMaps; +struct SegmentMaps : ArrayOf<AxisValueMap> +{ + inline int map (int value) const + { + /* The following special-cases are not part of OpenType, which requires + * that at least -1, 0, and +1 must be mapped. But we include these as + * part of a better error recovery scheme. */ + + if (!len) + return value; + + if (value <= array[0].fromCoord) + return value - array[0].fromCoord + array[0].toCoord; + + unsigned int i; + unsigned int count = len; + for (i = 1; i < count && value > array[i].fromCoord; i++) + ; + + if (value >= array[i].fromCoord) + return value - array[i].fromCoord + array[i].toCoord; + + if (unlikely (array[i-1].fromCoord == array[i].fromCoord)) + return array[i-1].toCoord; + + int denom = array[i].fromCoord - array[i-1].fromCoord; + return array[i-1].toCoord + + (array[i].toCoord - array[i-1].toCoord) * + (value - array[i-1].fromCoord + denom/2) / denom; + } + + DEFINE_SIZE_ARRAY (2, array); +}; /* * avar â Axis Variations Table @@ -80,6 +112,18 @@ struct avar return_trace (true); } + inline void map_coords (int *coords, unsigned int coords_length) const + { + unsigned int count = MIN<unsigned int> (coords_length, axisCount); + + const SegmentMaps *map = &axisSegmentMapsZ; + for (unsigned int i = 0; i < count; i++) + { + coords[i] = map->map (coords[i]); + map = &StructAfter<SegmentMaps> (*map); + } + } + protected: FixedVersion<>version; /* Version of the avar table * initially set to 0x00010000u */ diff --git a/src/hb-ot-var.cc b/src/hb-ot-var.cc index 76016e6..d4d16df 100644 --- a/src/hb-ot-var.cc +++ b/src/hb-ot-var.cc @@ -33,19 +33,24 @@ HB_SHAPER_DATA_ENSURE_DECLARE(ot, face) +/* + * fvar/avar + */ + static inline const OT::fvar& _get_fvar (hb_face_t *face) { if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::fvar); - hb_ot_layout_t * layout = hb_ot_layout_from_face (face); - return *(layout->fvar.get ()); } - -/* - * fvar/avar - */ +static inline const OT::avar& +_get_avar (hb_face_t *face) +{ + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::avar); + hb_ot_layout_t * layout = hb_ot_layout_from_face (face); + return *(layout->avar.get ()); +} /** * hb_ot_var_has_data: @@ -131,7 +136,8 @@ hb_ot_var_normalize_variations (hb_face_t *face, coords[axis_index] = fvar.normalize_axis_value (axis_index, variations[i].value); } - /* TODO avar */ + const OT::avar &avar = _get_avar (face); + avar.map_coords (coords, coords_length); } /** @@ -149,5 +155,6 @@ hb_ot_var_normalize_coords (hb_face_t *face, for (unsigned int i = 0; i < coords_length; i++) normalized_coords[i] = fvar.normalize_axis_value (i, design_coords[i]); - /* TODO avar */ + const OT::avar &avar = _get_avar (face); + avar.map_coords (normalized_coords, coords_length); } commit a42909057207cbed1ef95716170434c05beb0002 Author: Behdad Esfahbod <beh...@behdad.org> Date: Sun Jan 22 19:01:07 2017 -0800 [var] Flesh out --variations documentation diff --git a/util/options.cc b/util/options.cc index 8c79c4a..0f2e207 100644 --- a/util/options.cc +++ b/util/options.cc @@ -311,7 +311,7 @@ view_options_t::add_options (option_parser_t *parser) parser->add_group (entries, "view", "View options:", - "Options controlling output rendering", + "Options for output rendering", this); } @@ -340,7 +340,7 @@ shape_options_t::add_options (option_parser_t *parser) parser->add_group (entries, "shape", "Shape options:", - "Options controlling the shaping process", + "Options for the shaping process", this); const gchar *features_help = "Comma-separated list of font features\n" @@ -387,7 +387,7 @@ shape_options_t::add_options (option_parser_t *parser) parser->add_group (entries2, "features", "Features options:", - "Options controlling font features used", + "Options for font features used", this); } @@ -454,45 +454,20 @@ font_options_t::add_options (option_parser_t *parser) parser->add_group (entries, "font", "Font options:", - "Options controlling the font", + "Options for the font", this); const gchar *variations_help = "Comma-separated list of font variations\n" "\n" - " XXXXXXXXXXXXXXX\n" - " Features can be enabled or disabled, either globally or limited to\n" - " specific character ranges. The format for specifying feature settings\n" - " follows. All valid CSS font-feature-settings values other than 'normal'\n" + " Variations are set globally. The format for specifying variation settings\n" + " follows. All valid CSS font-variation-settings values other than 'normal'\n" " and 'inherited' are also accepted, though, not documented below.\n" "\n" - " The range indices refer to the positions between Unicode characters,\n" - " unless the --utf8-clusters is provided, in which case range indices\n" - " refer to UTF-8 byte indices. The position before the first character\n" - " is always 0.\n" - "\n" - " The format is Python-esque. Here is how it all works:\n" - "\n" - " Syntax: Value: Start: End:\n" - "\n" - " Setting value:\n" - " \"kern\" 1 0 â # Turn feature on\n" - " \"+kern\" 1 0 â # Turn feature on\n" - " \"-kern\" 0 0 â # Turn feature off\n" - " \"kern=0\" 0 0 â # Turn feature off\n" - " \"kern=1\" 1 0 â # Turn feature on\n" - " \"aalt=2\" 2 0 â # Choose 2nd alternate\n" - "\n" - " Setting index:\n" - " \"kern[]\" 1 0 â # Turn feature on\n" - " \"kern[:]\" 1 0 â # Turn feature on\n" - " \"kern[5:]\" 1 5 â # Turn feature on, partial\n" - " \"kern[:5]\" 1 0 5 # Turn feature on, partial\n" - " \"kern[3:5]\" 1 3 5 # Turn feature on, range\n" - " \"kern[3]\" 1 3 3+1 # Turn feature on, single char\n" + " The format is a tag, optionally followed by an equals sign, followed by a\n" + " number. For example:\n" "\n" - " Mixing it all:\n" - "\n" - " \"aalt[3:5]=2\" 2 3 5 # Turn 2nd alternate on for range"; + " \"wght=500\"\n" + " \"slnt=-7.5\"\n"; GOptionEntry entries2[] = { @@ -502,7 +477,7 @@ font_options_t::add_options (option_parser_t *parser) parser->add_group (entries2, "variations", "Varitions options:", - "Options controlling font variations used", + "Options for font variations used", this); } @@ -520,7 +495,7 @@ text_options_t::add_options (option_parser_t *parser) parser->add_group (entries, "text", "Text options:", - "Options controlling the input text", + "Options for the input text", this); } @@ -548,7 +523,7 @@ output_options_t::add_options (option_parser_t *parser) parser->add_group (entries, "output", "Output destination & format options:", - "Options controlling the destination and form of the output", + "Options for the destination & form of the output", this); } @@ -810,7 +785,7 @@ format_options_t::add_options (option_parser_t *parser) " text: [<glyph name or index>=<glyph cluster index within input>@<horizontal displacement>,<vertical displacement>+<horizontal advance>,<vertical advance>|...]\n" " json: [{\"g\": <glyph name or index>, \"ax\": <horizontal advance>, \"ay\": <vertical advance>, \"dx\": <horizontal displacement>, \"dy\": <vertical displacement>, \"cl\": <glyph cluster index within input>}, ...]\n" "\nOutput syntax options:", - "Options controlling the syntax of the output", + "Options for the syntax of the output", this); } commit 5ec96d30cad1592b5e468bd8ad1832dbaf0ad32b Author: Behdad Esfahbod <beh...@behdad.org> Date: Sun Jan 22 18:52:00 2017 -0800 [var] Adjust API in prep for 'avar' implementation The 'avar' table does not allow random access to axis maps, so change API to avoid quadratic-time implementation. Removed -hb_ot_var_normalize_axis_value(), added +hb_ot_var_normalize_variations() and +hb_ot_var_normalize_coords() instead. diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index b4ae15d..fcf4e52 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -448,7 +448,8 @@ hb_ot_var_has_data hb_ot_var_find_axis hb_ot_var_get_axis_count hb_ot_var_get_axes -hb_ot_var_normalize_axis_value +hb_ot_var_normalize_variations +hb_ot_var_normalize_coords </SECTION> <SECTION> diff --git a/src/Makefile.sources b/src/Makefile.sources index 279bc46..c74147c 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -109,6 +109,7 @@ HB_OT_sources = \ hb-ot-shape-fallback.cc \ hb-ot-shape-private.hh \ hb-ot-var.cc \ + hb-ot-var-avar-table.hh \ hb-ot-var-fvar-table.hh \ $(NULL) diff --git a/src/hb-font.cc b/src/hb-font.cc index a3f250d..ea45501 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -1570,22 +1570,15 @@ hb_font_set_variations (hb_font_t *font, return; } - hb_face_t *face = font->face; - - unsigned int coords_length = hb_ot_var_get_axis_count (face); + unsigned int coords_length = hb_ot_var_get_axis_count (font->face); int *normalized = coords_length ? (int *) calloc (coords_length, sizeof (int)) : NULL; if (unlikely (coords_length && !normalized)) return; - /* normalized is filled with zero already. */ - for (unsigned int i = 0; i < variations_length; i++) - { - unsigned int axis_index; - if (hb_ot_var_find_axis (face, variations[i].tag, &axis_index, NULL)) - normalized[axis_index] = hb_ot_var_normalize_axis_value (face, axis_index, variations[i].value); - } - + hb_ot_var_normalize_variations (font->face, + variations, variations_length, + normalized, coords_length); _hb_font_adopt_var_coords_normalized (font, normalized, coords_length); } @@ -1606,10 +1599,7 @@ hb_font_set_var_coords_design (hb_font_t *font, if (unlikely (coords_length && !normalized)) return; - hb_face_t *face = font->face; - for (unsigned int i = 0; i < coords_length; i++) - normalized[i] = hb_ot_var_normalize_axis_value (face, i, coords[i]); - + hb_ot_var_normalize_coords (font->face, coords_length, coords, normalized); _hb_font_adopt_var_coords_normalized (font, normalized, coords_length); } diff --git a/src/hb-ot-var.cc b/src/hb-ot-var.cc index 5080424..76016e6 100644 --- a/src/hb-ot-var.cc +++ b/src/hb-ot-var.cc @@ -27,6 +27,7 @@ #include "hb-open-type-private.hh" #include "hb-ot-layout-private.hh" +#include "hb-ot-var-avar-table.hh" #include "hb-ot-var-fvar-table.hh" #include "hb-ot-var.h" @@ -105,16 +106,48 @@ hb_ot_var_find_axis (hb_face_t *face, return fvar.find_axis (axis_tag, axis_index, axis_info); } + +/** + * hb_ot_var_normalize_variations: + * + * Since: 1.4.2 + **/ +void +hb_ot_var_normalize_variations (hb_face_t *face, + const hb_variation_t *variations, /* IN */ + unsigned int variations_length, + int *coords, /* OUT */ + unsigned int coords_length) +{ + for (unsigned int i = 0; i < coords_length; i++) + coords[i] = 0; + + const OT::fvar &fvar = _get_fvar (face); + for (unsigned int i = 0; i < variations_length; i++) + { + unsigned int axis_index; + if (hb_ot_var_find_axis (face, variations[i].tag, &axis_index, NULL) && + axis_index < coords_length) + coords[axis_index] = fvar.normalize_axis_value (axis_index, variations[i].value); + } + + /* TODO avar */ +} + /** - * hb_ot_var_normalize_axis_value: + * hb_ot_var_normalize_coords: * * Since: 1.4.2 **/ -int -hb_ot_var_normalize_axis_value (hb_face_t *face, - unsigned int axis_index, - float v) +void +hb_ot_var_normalize_coords (hb_face_t *face, + unsigned int coords_length, + const float *design_coords, /* IN */ + int *normalized_coords /* OUT */) { const OT::fvar &fvar = _get_fvar (face); - return fvar.normalize_axis_value (axis_index, v); + for (unsigned int i = 0; i < coords_length; i++) + normalized_coords[i] = fvar.normalize_axis_value (i, design_coords[i]); + + /* TODO avar */ } diff --git a/src/hb-ot-var.h b/src/hb-ot-var.h index 652a78d..bce7c7a 100644 --- a/src/hb-ot-var.h +++ b/src/hb-ot-var.h @@ -83,10 +83,18 @@ hb_ot_var_find_axis (hb_face_t *face, hb_ot_var_axis_t *axis_info); -HB_EXTERN int -hb_ot_var_normalize_axis_value (hb_face_t *face, - unsigned int axis_index, - float v); +HB_EXTERN void +hb_ot_var_normalize_variations (hb_face_t *face, + const hb_variation_t *variations, /* IN */ + unsigned int variations_length, + int *coords, /* OUT */ + unsigned int coords_length); + +HB_EXTERN void +hb_ot_var_normalize_coords (hb_face_t *face, + unsigned int coords_length, + const float *design_coords, /* IN */ + int *normalized_coords /* OUT */); HB_END_DECLS commit 8a577aaa0dd760409bcad1ae3d4f5fb561a62a4b Author: Behdad Esfahbod <beh...@behdad.org> Date: Sun Jan 22 18:22:40 2017 -0800 [var] Stub implementation of avar table diff --git a/src/hb-ot-var-avar-table.hh b/src/hb-ot-var-avar-table.hh new file mode 100644 index 0000000..a041934 --- /dev/null +++ b/src/hb-ot-var-avar-table.hh @@ -0,0 +1,99 @@ +/* + * Copyright © 2017 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_OT_VAR_AVAR_TABLE_HH +#define HB_OT_VAR_AVAR_TABLE_HH + +#include "hb-open-type-private.hh" +#include "hb-ot-var.h" + +namespace OT { + + +struct AxisValueMap +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + public: + F2DOT14 fromCoord; /* A normalized coordinate value obtained using + * default normalization. */ + F2DOT14 toCoord; /* The modified, normalized coordinate value. */ + + public: + DEFINE_SIZE_STATIC (4); +}; + +typedef ArrayOf<AxisValueMap> SegmentMaps; + +/* + * avar â Axis Variations Table + */ + +struct avar +{ + static const hb_tag_t tableTag = HB_OT_TAG_avar; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (unlikely (!(version.sanitize (c) && + version.major == 1 && + c->check_struct (this)))) + return_trace (false); + + const SegmentMaps *map = &axisSegmentMapsZ; + unsigned int count = axisCount; + for (unsigned int i = 0; i < count; i++) + { + if (unlikely (!map->sanitize (c))) + return_trace (false); + map = &StructAfter<SegmentMaps> (*map); + } + + return_trace (true); + } + + protected: + FixedVersion<>version; /* Version of the avar table + * initially set to 0x00010000u */ + USHORT reserved; /* This field is permanently reserved. Set to 0. */ + USHORT axisCount; /* The number of variation axes in the font. This + * must be the same number as axisCount in the + * 'fvar' table. */ + SegmentMaps axisSegmentMapsZ; + + public: + DEFINE_SIZE_MIN (8); +}; + +} /* namespace OT */ + + +#endif /* HB_OT_VAR_AVAR_TABLE_HH */ commit 7647a05a0b37c53465560952b412db4e590f2716 Author: Behdad Esfahbod <beh...@behdad.org> Date: Sun Jan 22 17:47:49 2017 -0800 Minor diff --git a/src/hb-font.cc b/src/hb-font.cc index 3140ee4..a3f250d 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -1639,9 +1639,12 @@ hb_font_set_var_coords_normalized (hb_font_t *font, /** * hb_font_set_var_coords_normalized: * + * Return value is valid as long as variation coordinates of the font + * are not modified. + * * Since: 1.4.2 */ -int * +const int * hb_font_get_var_coords_normalized (hb_font_t *font, unsigned int *length) { diff --git a/src/hb-font.h b/src/hb-font.h index fce4206..e2e5979 100644 --- a/src/hb-font.h +++ b/src/hb-font.h @@ -618,7 +618,7 @@ hb_font_set_var_coords_normalized (hb_font_t *font, const int *coords, /* 2.14 normalized */ unsigned int coords_length); -HB_EXTERN int * +HB_EXTERN const int * hb_font_get_var_coords_normalized (hb_font_t *font, unsigned int *length); diff --git a/src/hb-ft.cc b/src/hb-ft.cc index 496fff2..48d6a0e 100644 --- a/src/hb-ft.cc +++ b/src/hb-ft.cc @@ -742,7 +742,7 @@ hb_ft_font_set_funcs (hb_font_t *font) } unsigned int num_coords; - int *coords = hb_font_get_var_coords_normalized (font, &num_coords); + const int *coords = hb_font_get_var_coords_normalized (font, &num_coords); if (num_coords) { FT_Fixed *ft_coords = (FT_Fixed *) calloc (num_coords, sizeof (FT_Fixed)); diff --git a/util/helper-cairo.cc b/util/helper-cairo.cc index df5173b..2e2952b 100644 --- a/util/helper-cairo.cc +++ b/util/helper-cairo.cc @@ -104,13 +104,17 @@ helper_cairo_create_scaled_font (const font_options_t *font_opts) else { unsigned int num_coords; - int *coords = hb_font_get_var_coords_normalized (font, &num_coords); + const int *coords = hb_font_get_var_coords_normalized (font, &num_coords); if (num_coords) { - FT_Fixed ft_coords[num_coords]; - for (unsigned int i = 0; i < num_coords; i++) - ft_coords[i] = coords[i] << 2; - FT_Set_Var_Blend_Coordinates (ft_face, num_coords, ft_coords); + FT_Fixed *ft_coords = (FT_Fixed *) calloc (num_coords, sizeof (FT_Fixed)); + if (ft_coords) + { + for (unsigned int i = 0; i < num_coords; i++) + ft_coords[i] = coords[i] << 2; + FT_Set_Var_Blend_Coordinates (ft_face, num_coords, ft_coords); + free (ft_coords); + } } cairo_face = cairo_ft_font_face_create_for_ft_face (ft_face, 0);
_______________________________________________ HarfBuzz mailing list HarfBuzz@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/harfbuzz