From 71b65eb27dd0867f51d9906887b9e372eb37f54a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 7 Oct 2018 18:41:52 +0200 Subject: [PATCH] Add API for setting invisible-codepoint Fixes https://github.com/harfbuzz/harfbuzz/issues/1216 New API: hb_buffer_set_invisible_codepoint() hb_buffer_get_invisible_codepoint() hb-shape / hb-view --invisible-codepoint --- docs/harfbuzz-sections.txt | 2 ++ src/hb-buffer.cc | 42 ++++++++++++++++++++++++++++++++++++++ src/hb-buffer.h | 7 +++++++ src/hb-buffer.hh | 1 + src/hb-ot-shape.cc | 8 ++++---- util/options.cc | 1 + util/options.hh | 3 +++ 7 files changed, 60 insertions(+), 4 deletions(-) diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index b69c16860..7426a43a3 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -67,6 +67,8 @@ hb_buffer_set_user_data hb_buffer_get_user_data hb_buffer_get_glyph_infos hb_buffer_get_glyph_positions +hb_buffer_get_invisible_codepoint +hb_buffer_set_invisible_codepoint hb_buffer_set_replacement_codepoint hb_buffer_get_replacement_codepoint hb_buffer_normalize_glyphs diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc index b93b243c9..0b8593f84 100644 --- a/src/hb-buffer.cc +++ b/src/hb-buffer.cc @@ -219,6 +219,7 @@ hb_buffer_t::reset (void) unicode = hb_unicode_funcs_reference (hb_unicode_funcs_get_default ()); flags = HB_BUFFER_FLAG_DEFAULT; replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT; + invisible = 0; clear (); } @@ -665,6 +666,7 @@ DEFINE_NULL_INSTANCE (hb_buffer_t) = HB_BUFFER_FLAG_DEFAULT, HB_BUFFER_CLUSTER_LEVEL_DEFAULT, HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT, + 0, /* invisible */ HB_BUFFER_SCRATCH_FLAG_DEFAULT, HB_BUFFER_MAX_LEN_DEFAULT, HB_BUFFER_MAX_OPS_DEFAULT, @@ -1166,6 +1168,46 @@ hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer) } +/** + * hb_buffer_set_invisible_codepoint: + * @buffer: an #hb_buffer_t. + * @invisible: the invisible #hb_codepoint_t + * + * Sets the #hb_codepoint_t that replaces invisible characters in + * the shaping result. If set to zero (default), the glyph for the + * U+0020 SPACE character is used. Otherwise, this value is used + * verbatim. + * + * Since: REPLACEME + **/ +void +hb_buffer_set_invisible_codepoint (hb_buffer_t *buffer, + hb_codepoint_t invisible) +{ + if (unlikely (hb_object_is_inert (buffer))) + return; + + buffer->invisible = invisible; +} + +/** + * hb_buffer_get_invisible_codepoint: + * @buffer: an #hb_buffer_t. + * + * See hb_buffer_set_invisible_codepoint(). + * + * Return value: + * The @buffer invisible #hb_codepoint_t. + * + * Since: REPLACEME + **/ +hb_codepoint_t +hb_buffer_get_invisible_codepoint (hb_buffer_t *buffer) +{ + return buffer->invisible; +} + + /** * hb_buffer_reset: * @buffer: an #hb_buffer_t. diff --git a/src/hb-buffer.h b/src/hb-buffer.h index 4c746f401..d99ae7d64 100644 --- a/src/hb-buffer.h +++ b/src/hb-buffer.h @@ -341,6 +341,13 @@ hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer, HB_EXTERN hb_codepoint_t hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer); +HB_EXTERN void +hb_buffer_set_invisible_codepoint (hb_buffer_t *buffer, + hb_codepoint_t invisible); + +HB_EXTERN hb_codepoint_t +hb_buffer_get_invisible_codepoint (hb_buffer_t *buffer); + HB_EXTERN void hb_buffer_reset (hb_buffer_t *buffer); diff --git a/src/hb-buffer.hh b/src/hb-buffer.hh index 33ddcbc87..9126822eb 100644 --- a/src/hb-buffer.hh +++ b/src/hb-buffer.hh @@ -93,6 +93,7 @@ struct hb_buffer_t hb_buffer_flags_t flags; /* BOT / EOT / etc. */ hb_buffer_cluster_level_t cluster_level; hb_codepoint_t replacement; /* U+FFFD or something else. */ + hb_codepoint_t invisible; /* 0 or something else. */ hb_buffer_scratch_flags_t scratch_flags; /* Have space-fallback, etc. */ unsigned int max_len; /* Maximum allowed len. */ int max_ops; /* Maximum allowed operations. */ diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 453d995a2..3b79ef460 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -548,15 +548,15 @@ hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c) if (i == count) return; - hb_codepoint_t space; + hb_codepoint_t invisible = c->buffer->invisible; if (!(buffer->flags & HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES) && - c->font->get_nominal_glyph (' ', &space)) + (invisible || c->font->get_nominal_glyph (' ', &invisible))) { - /* Replace default-ignorables with a zero-advance space glyph. */ + /* Replace default-ignorables with a zero-advance invisible glyph. */ for (/*continue*/; i < count; i++) { if (_hb_glyph_info_is_default_ignorable (&info[i])) - info[i].codepoint = space; + info[i].codepoint = invisible; } } else diff --git a/util/options.cc b/util/options.cc index bfb11b457..8e17df2a6 100644 --- a/util/options.cc +++ b/util/options.cc @@ -415,6 +415,7 @@ shape_options_t::add_options (option_parser_t *parser) {"eot", 0, 0, G_OPTION_ARG_NONE, &this->eot, "Treat text as end-of-paragraph", nullptr}, {"preserve-default-ignorables",0, 0, G_OPTION_ARG_NONE, &this->preserve_default_ignorables, "Preserve Default-Ignorable characters", nullptr}, {"remove-default-ignorables",0, 0, G_OPTION_ARG_NONE, &this->remove_default_ignorables, "Remove Default-Ignorable characters", nullptr}, + {"invisible-codepoint",0, 0, G_OPTION_ARG_INT, &this->invisible_codepoint, "Value to replace Default-Ignorables with", nullptr}, {"utf8-clusters", 0, 0, G_OPTION_ARG_NONE, &this->utf8_clusters, "Use UTF8 byte indices, not char indices", nullptr}, {"cluster-level", 0, 0, G_OPTION_ARG_INT, &this->cluster_level, "Cluster merging level (default: 0)", "0/1/2"}, {"normalize-glyphs",0, 0, G_OPTION_ARG_NONE, &this->normalize_glyphs, "Rearrange glyph clusters in nominal order", nullptr}, diff --git a/util/options.hh b/util/options.hh index 40e1ab892..3d7b96dd9 100644 --- a/util/options.hh +++ b/util/options.hh @@ -155,6 +155,7 @@ struct shape_options_t : option_group_t num_features = 0; shapers = nullptr; utf8_clusters = false; + invisible_codepoint = 0; cluster_level = HB_BUFFER_CLUSTER_LEVEL_DEFAULT; normalize_glyphs = false; verify = false; @@ -185,6 +186,7 @@ struct shape_options_t : option_group_t (preserve_default_ignorables ? HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES : 0) | (remove_default_ignorables ? HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES : 0) | 0)); + hb_buffer_set_invisible_codepoint (buffer, invisible_codepoint); hb_buffer_set_cluster_level (buffer, cluster_level); hb_buffer_guess_segment_properties (buffer); } @@ -435,6 +437,7 @@ struct shape_options_t : option_group_t unsigned int num_features; char **shapers; hb_bool_t utf8_clusters; + hb_codepoint_t invisible_codepoint; hb_buffer_cluster_level_t cluster_level; hb_bool_t normalize_glyphs; hb_bool_t verify;