docs/harfbuzz-sections.txt | 2 ++ src/hb-buffer.cc | 42 ++++++++++++++++++++++++++++++++++++++++++ src/hb-buffer.h | 7 +++++++ src/hb-buffer.hh | 1 + src/hb-ot-font.cc | 28 ++++++++++++++-------------- src/hb-ot-shape.cc | 8 ++++---- test/api/test-multithread.c | 6 +++--- util/options.cc | 1 + util/options.hh | 3 +++ 9 files changed, 77 insertions(+), 21 deletions(-)
New commits: commit 71b65eb27dd0867f51d9906887b9e372eb37f54a Author: Behdad Esfahbod <beh...@behdad.org> Date: Sun Oct 7 18:41:52 2018 +0200 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 diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index b69c1686..7426a43a 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 b93b243c..0b8593f8 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, @@ -1167,6 +1169,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 4c746f40..d99ae7d6 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 33ddcbc8..9126822e 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 453d995a..3b79ef46 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 bfb11b45..8e17df2a 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 40e1ab89..3d7b96dd 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; commit 13da3be0b342e8e2f060eba8753c6957c477c4ee Author: Behdad Esfahbod <beh...@behdad.org> Date: Sun Oct 7 18:23:45 2018 +0200 [ot-font] Load hmtx/vmtx lazily Since we have get_*_advanes() API now, the overhead is once per shape, not once per glyph. Only cmap is warmed-up at set_funcs() time now. diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 637814d9..fa8d5a3c 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -73,7 +73,7 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, void *user_data HB_UNUSED) { const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; - const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx.get_relaxed (); + const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx.get (); for (unsigned int i = 0; i < count; i++) { @@ -93,7 +93,7 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, void *user_data HB_UNUSED) { const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; - const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx.get_relaxed (); + const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx.get (); for (unsigned int i = 0; i < count; i++) { @@ -162,11 +162,12 @@ hb_ot_get_font_h_extents (hb_font_t *font, void *user_data HB_UNUSED) { const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; - metrics->ascender = font->em_scale_y (ot_face->hmtx.get_relaxed ()->ascender); - metrics->descender = font->em_scale_y (ot_face->hmtx.get_relaxed ()->descender); - metrics->line_gap = font->em_scale_y (ot_face->hmtx.get_relaxed ()->line_gap); + const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx.get (); + metrics->ascender = font->em_scale_y (hmtx.ascender); + metrics->descender = font->em_scale_y (hmtx.descender); + metrics->line_gap = font->em_scale_y (hmtx.line_gap); // TODO Hook up variations. - return ot_face->hmtx.get_relaxed ()->has_font_extents; + return hmtx.has_font_extents; } static hb_bool_t @@ -176,11 +177,12 @@ hb_ot_get_font_v_extents (hb_font_t *font, void *user_data HB_UNUSED) { const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; - metrics->ascender = font->em_scale_x (ot_face->vmtx.get_relaxed ()->ascender); - metrics->descender = font->em_scale_x (ot_face->vmtx.get_relaxed ()->descender); - metrics->line_gap = font->em_scale_x (ot_face->vmtx.get_relaxed ()->line_gap); + const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx.get (); + metrics->ascender = font->em_scale_x (vmtx.ascender); + metrics->descender = font->em_scale_x (vmtx.descender); + metrics->line_gap = font->em_scale_x (vmtx.line_gap); // TODO Hook up variations. - return ot_face->vmtx.get_relaxed ()->has_font_extents; + return vmtx.has_font_extents; } #ifdef HB_USE_ATEXIT @@ -244,10 +246,8 @@ hb_ot_font_set_funcs (hb_font_t *font) if (unlikely (!hb_ot_shaper_face_data_ensure (font->face))) return; hb_ot_face_data_t *ot_face = hb_ot_face_data (font->face); - /* Load them lazies. We access them with get_relaxed() for performance. */ + /* Load them lazy. We access it with get_relaxed() for performance. */ ot_face->cmap.get (); - ot_face->hmtx.get (); - ot_face->vmtx.get (); hb_font_set_funcs (font, _hb_ot_get_font_funcs (), commit 856db4c9184e39c0457cc07c815f90058937c8a2 Author: Behdad Esfahbod <beh...@behdad.org> Date: Sun Oct 7 18:21:15 2018 +0200 Minor diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 280ade5b..637814d9 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -187,7 +187,7 @@ hb_ot_get_font_v_extents (hb_font_t *font, static void free_static_ot_funcs (void); #endif -static struct hb_ot_face_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot_face_funcs_lazy_loader_t> +static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot_font_funcs_lazy_loader_t> { static inline hb_font_funcs_t *create (void) { commit f92330b5e0b1a5a61768494bd7081e3fc235b182 Author: Behdad Esfahbod <beh...@behdad.org> Date: Sun Oct 7 17:51:50 2018 +0200 Minor diff --git a/test/api/test-multithread.c b/test/api/test-multithread.c index 72a1a178..58a637ca 100644 --- a/test/api/test-multithread.c +++ b/test/api/test-multithread.c @@ -135,7 +135,7 @@ main (int argc, char **argv) gchar *default_path = g_strdup (font_path); #endif - char *path = argc > 1 ? argv[1] : (char *) default_path; + char *path = argc > 1 && *argv[1] ? argv[1] : (char *) default_path; if (argc > 2) num_threads = atoi (argv[2]); if (argc > 3) @@ -143,8 +143,8 @@ main (int argc, char **argv) if (argc > 4) text = argv[4]; - // Dummy call to alleviate _guess_segment_properties thread safety-ness - // https://github.com/harfbuzz/harfbuzz/issues/1191 + /* Dummy call to alleviate _guess_segment_properties thread safety-ness + * https://github.com/harfbuzz/harfbuzz/issues/1191 */ hb_language_get_default (); hb_blob_t *blob = hb_blob_create_from_file (path); _______________________________________________ HarfBuzz mailing list HarfBuzz@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/harfbuzz