src/hb-ot-font.cc | 4 src/hb-ot-layout-gsubgpos-private.hh | 2 src/hb-ot-layout-private.hh | 61 +++++----- src/hb-ot-shape-complex-thai.cc | 2 test/shaping/fonts/sha1sum/8240789f6d12d4cfc4b5e8e6f246c3701bcf861f.ttf |binary test/shaping/fonts/sha1sum/MANIFEST | 1 test/shaping/tests/fuzzed.tests | 1 util/helper-cairo.cc | 7 - util/main-font-text.hh | 22 +++ util/options.cc | 24 ++- util/options.hh | 53 +++++--- 11 files changed, 114 insertions(+), 63 deletions(-)
New commits: commit df698f3299d92867e3305715f675b2621c316acd Author: Behdad Esfahbod <[email protected]> Date: Tue Nov 3 12:15:12 2015 -0800 [ot-font] Fix hmtx table length checking, *again* Exactly the same problem that I fixed in 63ef0b41dc48d6112d1918c1b1de9de8ea90adb5 I rewrote the table checking yesterday in 67f8821fb25d9bd55719f5e29a582ae1af4b02b3 and introduced the exact same issue again. :( Good thing we have ongoing fuzzing going now. Was discovered immediately by libFuzzer. Thanks kcc! https://github.com/behdad/harfbuzz/issues/139#issuecomment-153449473 Fixes https://github.com/behdad/harfbuzz/issues/156 diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index bde63fa..94c31b3 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -59,11 +59,11 @@ struct hb_ot_face_metrics_accelerator_t /* Cap num_metrics() and num_advances() based on table length. */ unsigned int len = hb_blob_get_length (this->blob); - if (unlikely (this->num_advances * 4 < len)) + if (unlikely (this->num_advances * 4 > len)) this->num_advances = len / 4; this->num_metrics = this->num_advances + (len - 4 * this->num_advances) / 2; - /* We MUSt set num_metrics to zero if num_advances is zero. + /* We MUST set num_metrics to zero if num_advances is zero. * Our get_advance() depends on that. */ if (unlikely (!this->num_advances)) { diff --git a/test/shaping/fonts/sha1sum/8240789f6d12d4cfc4b5e8e6f246c3701bcf861f.ttf b/test/shaping/fonts/sha1sum/8240789f6d12d4cfc4b5e8e6f246c3701bcf861f.ttf new file mode 100644 index 0000000..8eed14d Binary files /dev/null and b/test/shaping/fonts/sha1sum/8240789f6d12d4cfc4b5e8e6f246c3701bcf861f.ttf differ diff --git a/test/shaping/fonts/sha1sum/MANIFEST b/test/shaping/fonts/sha1sum/MANIFEST index 902fa00..785e6ef 100644 --- a/test/shaping/fonts/sha1sum/MANIFEST +++ b/test/shaping/fonts/sha1sum/MANIFEST @@ -17,6 +17,7 @@ 757ebd573617a24aa9dfbf0b885c54875c6fe06b.ttf 7e14e7883ed152baa158b80e207b66114c823a8b.ttf 813c2f8e5512187fd982417a7fb4286728e6f4a8.ttf +8240789f6d12d4cfc4b5e8e6f246c3701bcf861f.ttf 8454d22037f892e76614e1645d066689a0200e61.ttf 8a9fea2a7384f2116e5b84a9b31f83be7850ce21.ttf a919b33197965846f21074b24e30250d67277bce.ttf diff --git a/test/shaping/tests/fuzzed.tests b/test/shaping/tests/fuzzed.tests index 6bb30b0..64e96d7 100644 --- a/test/shaping/tests/fuzzed.tests +++ b/test/shaping/tests/fuzzed.tests @@ -3,3 +3,4 @@ fonts/sha1sum/5a5daf5eb5a4db77a2baa3ad9c7a6ed6e0655fa8.ttf:--font-funcs=ot:U+004 fonts/sha1sum/0509e80afb379d16560e9e47bdd7d888bebdebc6.ttf:--font-funcs=ot:U+0041:[gid0=0+1000] fonts/sha1sum/641bd9db850193064d17575053ae2bf8ec149ddc.ttf:--font-funcs=ot:U+0041:[gid0=0+1000] fonts/sha1sum/375d6ae32a3cbe52fbf81a4e5777e3377675d5a3.ttf:--font-funcs=ot:U+0041:[gid0=0+4352] +fonts/sha1sum/8240789f6d12d4cfc4b5e8e6f246c3701bcf861f.ttf:--font-funcs=ot:U+0041:[gid0=0+2304] commit 3530cc2d7c3b7102902cb0e38b0bf9f46188078d Author: Behdad Esfahbod <[email protected]> Date: Tue Nov 3 11:34:47 2015 -0800 [util] Fix option-parsing leaks diff --git a/util/helper-cairo.cc b/util/helper-cairo.cc index d576c3f..8960df9 100644 --- a/util/helper-cairo.cc +++ b/util/helper-cairo.cc @@ -349,10 +349,13 @@ helper_cairo_create_context (double w, double h, unsigned int fr, fg, fb, fa, br, bg, bb, ba; + const char *color; br = bg = bb = 0; ba = 255; - sscanf (view_opts->back + (*view_opts->back=='#'), "%2x%2x%2x%2x", &br, &bg, &bb, &ba); + color = view_opts->back ? view_opts->back : DEFAULT_BACK; + sscanf (color + (*color=='#'), "%2x%2x%2x%2x", &br, &bg, &bb, &ba); fr = fg = fb = 0; fa = 255; - sscanf (view_opts->fore + (*view_opts->fore=='#'), "%2x%2x%2x%2x", &fr, &fg, &fb, &fa); + color = view_opts->fore ? view_opts->fore : DEFAULT_FORE; + sscanf (color + (*color=='#'), "%2x%2x%2x%2x", &fr, &fg, &fb, &fa); cairo_content_t content; if (!view_opts->annotate && ba == 255 && br == bg && bg == bb && fr == fg && fg == fb) diff --git a/util/main-font-text.hh b/util/main-font-text.hh index 628cdf9..7e8bffe 100644 --- a/util/main-font-text.hh +++ b/util/main-font-text.hh @@ -31,6 +31,22 @@ /* main() body for utilities taking font and processing text.*/ +static char * +locale_to_utf8 (char *s) +{ + char *t; + GError *error = NULL; + + t = g_locale_to_utf8 (s, -1, NULL, NULL, &error); + if (!t) + { + fail (true, "Failed converting text to UTF-8"); + } + + return t; +} + + template <typename consumer_t, int default_font_size, int subpixel_bits> struct main_font_text_t { @@ -46,14 +62,14 @@ struct main_font_text_t options.parse (&argc, &argv); argc--, argv++; - if (argc && !font_opts.font_file) font_opts.font_file = argv[0], argc--, argv++; - if (argc && !input.text && !input.text_file) input.text = argv[0], argc--, argv++; + if (argc && !font_opts.font_file) font_opts.font_file = locale_to_utf8 (argv[0]), argc--, argv++; + if (argc && !input.text && !input.text_file) input.text = locale_to_utf8 (argv[0]), argc--, argv++; if (argc) fail (true, "Too many arguments on the command line"); if (!font_opts.font_file) options.usage (); if (!input.text && !input.text_file) - input.text_file = "-"; + input.text_file = g_strdup ("-"); consumer.init (&font_opts); diff --git a/util/options.cc b/util/options.cc index 60f5268..ca8f906 100644 --- a/util/options.cc +++ b/util/options.cc @@ -601,25 +601,26 @@ const char * text_options_t::get_line (unsigned int *len) { if (text) { - if (text_len == (unsigned int) -1) - text_len = strlen (text); + if (!line) line = text; + if (line_len == (unsigned int) -1) + line_len = strlen (line); - if (!text_len) { + if (!line_len) { *len = 0; return NULL; } - const char *ret = text; - const char *p = (const char *) memchr (text, '\n', text_len); + const char *ret = line; + const char *p = (const char *) memchr (line, '\n', line_len); unsigned int ret_len; if (!p) { - ret_len = text_len; - text += ret_len; - text_len = 0; + ret_len = line_len; + line += ret_len; + line_len = 0; } else { ret_len = p - ret; - text += ret_len + 1; - text_len -= ret_len + 1; + line += ret_len + 1; + line_len -= ret_len + 1; } *len = ret_len; diff --git a/util/options.hh b/util/options.hh index f1ec8cf..9dc4433 100644 --- a/util/options.hh +++ b/util/options.hh @@ -150,19 +150,24 @@ struct view_options_t : option_group_t { view_options_t (option_parser_t *parser) { annotate = false; - fore = DEFAULT_FORE; - back = DEFAULT_BACK; + fore = NULL; + back = NULL; line_space = 0; margin.t = margin.r = margin.b = margin.l = DEFAULT_MARGIN; add_options (parser); } + ~view_options_t (void) + { + g_free (fore); + g_free (back); + } void add_options (option_parser_t *parser); hb_bool_t annotate; - const char *fore; - const char *back; + char *fore; + char *back; double line_space; struct margin_t { double t, r, b, l; @@ -188,6 +193,9 @@ struct shape_options_t : option_group_t } ~shape_options_t (void) { + g_free (direction); + g_free (language); + g_free (script); free (features); g_strfreev (shapers); } @@ -254,9 +262,9 @@ struct shape_options_t : option_group_t } /* Buffer properties */ - const char *direction; - const char *language; - const char *script; + char *direction; + char *language; + char *script; /* Buffer flags */ hb_bool_t bot; @@ -290,6 +298,8 @@ struct font_options_t : option_group_t add_options (parser); } ~font_options_t (void) { + g_free (font_file); + g_free (font_funcs); hb_font_destroy (font); } @@ -297,13 +307,13 @@ struct font_options_t : option_group_t hb_font_t *get_font (void) const; - const char *font_file; + char *font_file; int face_index; int default_font_size; unsigned int subpixel_bits; mutable double font_size_x; mutable double font_size_y; - const char *font_funcs; + char *font_funcs; private: mutable hb_font_t *font; @@ -321,11 +331,16 @@ struct text_options_t : option_group_t fp = NULL; gs = NULL; - text_len = (unsigned int) -1; + line = NULL; + line_len = (unsigned int) -1; add_options (parser); } ~text_options_t (void) { + g_free (text_before); + g_free (text_after); + g_free (text); + g_free (text_file); if (gs) g_string_free (gs, true); if (fp) @@ -339,21 +354,21 @@ struct text_options_t : option_group_t g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Only one of text and text-file can be set"); - }; const char *get_line (unsigned int *len); - const char *text_before; - const char *text_after; + char *text_before; + char *text_after; - const char *text; - const char *text_file; + char *text; + char *text_file; private: FILE *fp; GString *gs; - unsigned int text_len; + char *line; + unsigned int line_len; }; struct output_options_t : option_group_t @@ -370,6 +385,8 @@ struct output_options_t : option_group_t add_options (parser); } ~output_options_t (void) { + g_free (output_file); + g_free (output_format); if (fp) fclose (fp); } @@ -393,8 +410,8 @@ struct output_options_t : option_group_t FILE *get_file_handle (void); - const char *output_file; - const char *output_format; + char *output_file; + char *output_format; const char **supported_formats; bool explicit_output_format; commit 642135f3b2d6d6eb800153c76c4718239733c0e6 Author: Behdad Esfahbod <[email protected]> Date: Tue Nov 3 11:26:34 2015 -0800 [util] In --debug mode, duplicate font data This has the effect that the font data will end up in a memory section malloc()ed exactly to its size. This gives us better valgrind detection of out-of-bounds access. Previously, the font data was placed in a mmap()ed section or GString-allocated area, which didn't have proper protections at the end when running under valgrind. diff --git a/util/options.cc b/util/options.cc index 0005f5c..60f5268 100644 --- a/util/options.cc +++ b/util/options.cc @@ -538,6 +538,9 @@ font_options_t::get_font (void) const } } + if (debug) + mm = HB_MEMORY_MODE_DUPLICATE; + blob = hb_blob_create (font_data, len, mm, user_data, destroy); } commit ed2024ef93ac3af214082016e5aa8c14db9d7515 Author: Behdad Esfahbod <[email protected]> Date: Mon Nov 2 17:58:12 2015 -0800 [perf] Micro-optimize diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh index f1a101c..e13eaae 100644 --- a/src/hb-ot-layout-private.hh +++ b/src/hb-ot-layout-private.hh @@ -223,19 +223,24 @@ enum { static inline void _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode) { - unsigned int gen_cat = (unsigned int) unicode->general_category (info->codepoint); + unsigned int u = info->codepoint; + unsigned int gen_cat = (unsigned int) unicode->general_category (u); unsigned int props = gen_cat; - if (unlikely (unicode->is_default_ignorable (info->codepoint))) + if (u >= 0x80) { - props |= UPROPS_MASK_IGNORABLE; - if (info->codepoint == 0x200Cu) props |= UPROPS_MASK_ZWNJ; - if (info->codepoint == 0x200Du) props |= UPROPS_MASK_ZWJ; - } - else if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (gen_cat))) - { - props |= unicode->modified_combining_class (info->codepoint)<<8; + if (unlikely (unicode->is_default_ignorable (u))) + { + props |= UPROPS_MASK_IGNORABLE; + if (u == 0x200Cu) props |= UPROPS_MASK_ZWNJ; + if (u == 0x200Du) props |= UPROPS_MASK_ZWJ; + } + else if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (gen_cat))) + { + props |= unicode->modified_combining_class (info->codepoint)<<8; + } } + info->unicode_props() = props; } commit 76a5310a830c7ae12037b768c5043bef0ff733a0 Author: Behdad Esfahbod <[email protected]> Date: Mon Nov 2 17:52:45 2015 -0800 Remove irrelevant comment I tried moving the is_default_ignorable() function to an INTERNAL function. That made the binary size grow by 5k AND things got a tad bit slower! diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh index eab4ac6..f1a101c 100644 --- a/src/hb-ot-layout-private.hh +++ b/src/hb-ot-layout-private.hh @@ -226,7 +226,6 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *uni unsigned int gen_cat = (unsigned int) unicode->general_category (info->codepoint); unsigned int props = gen_cat; - /* XXX This wouldn't be inlined, or at least not while is_default_ignorable() is inline. */ if (unlikely (unicode->is_default_ignorable (info->codepoint))) { props |= UPROPS_MASK_IGNORABLE; commit 8259669fbd1b070fc02287325894caf1bc4d590e Author: Behdad Esfahbod <[email protected]> Date: Mon Nov 2 17:44:05 2015 -0800 Minor diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh index fb411db..1390a2e 100644 --- a/src/hb-ot-layout-gsubgpos-private.hh +++ b/src/hb-ot-layout-gsubgpos-private.hh @@ -835,8 +835,8 @@ static inline bool ligate_input (hb_apply_context_t *c, _hb_glyph_info_set_lig_props_for_ligature (&buffer->cur(), lig_id, total_component_count); if (_hb_glyph_info_get_general_category (&buffer->cur()) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) { - _hb_glyph_info_set_general_category (&buffer->cur(), HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER); _hb_glyph_info_set_modified_combining_class (&buffer->cur(), 0); + _hb_glyph_info_set_general_category (&buffer->cur(), HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER); } } c->replace_glyph_with_ligature (lig_glyph, klass); diff --git a/src/hb-ot-shape-complex-thai.cc b/src/hb-ot-shape-complex-thai.cc index 8a8f2f7..51a1a10 100644 --- a/src/hb-ot-shape-complex-thai.cc +++ b/src/hb-ot-shape-complex-thai.cc @@ -330,7 +330,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan, if (unlikely (buffer->in_error)) return; - /* Make Nikhahit be recognized as a mark when zeroing widths. */ + /* Make Nikhahit be recognized as a ccc=0 mark when zeroing widths. */ unsigned int end = buffer->out_len; _hb_glyph_info_set_general_category (&buffer->out_info[end - 2], HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK); commit 9382c471eabce8d36d3a73c97499ab60af422716 Author: Behdad Esfahbod <[email protected]> Date: Mon Nov 2 17:36:51 2015 -0800 Combine unicode_props0/1 into a uint16 Slightly faster. In prep for more changes. diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh index 075a568..eab4ac6 100644 --- a/src/hb-ot-layout-private.hh +++ b/src/hb-ot-layout-private.hh @@ -180,8 +180,7 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout); */ /* buffer var allocations, used during the entire shaping process */ -#define unicode_props0() var2.u8[0] -#define unicode_props1() var2.u8[1] +#define unicode_props() var2.u16[0] /* buffer var allocations, used during the GSUB/GPOS processing */ #define glyph_props() var1.u16[0] /* GDEF glyph properties */ @@ -215,49 +214,56 @@ _next_syllable (hb_buffer_t *buffer, unsigned int start) /* unicode_props */ enum { - MASK0_ZWJ = 0x20u, - MASK0_ZWNJ = 0x40u, - MASK0_IGNORABLE = 0x80u, - MASK0_GEN_CAT = 0x1Fu + UPROPS_MASK_ZWJ = 0x20u, + UPROPS_MASK_ZWNJ = 0x40u, + UPROPS_MASK_IGNORABLE = 0x80u, + UPROPS_MASK_GEN_CAT = 0x1Fu }; static inline void _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode) { unsigned int gen_cat = (unsigned int) unicode->general_category (info->codepoint); + unsigned int props = gen_cat; + /* XXX This wouldn't be inlined, or at least not while is_default_ignorable() is inline. */ - info->unicode_props0() = gen_cat | - (unicode->is_default_ignorable (info->codepoint) ? MASK0_IGNORABLE : 0) | - (info->codepoint == 0x200Cu ? MASK0_ZWNJ : 0) | - (info->codepoint == 0x200Du ? MASK0_ZWJ : 0); - info->unicode_props1() = unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (gen_cat)) ? - unicode->modified_combining_class (info->codepoint) : 0; + if (unlikely (unicode->is_default_ignorable (info->codepoint))) + { + props |= UPROPS_MASK_IGNORABLE; + if (info->codepoint == 0x200Cu) props |= UPROPS_MASK_ZWNJ; + if (info->codepoint == 0x200Du) props |= UPROPS_MASK_ZWJ; + } + else if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (gen_cat))) + { + props |= unicode->modified_combining_class (info->codepoint)<<8; + } + info->unicode_props() = props; } static inline void _hb_glyph_info_set_general_category (hb_glyph_info_t *info, hb_unicode_general_category_t gen_cat) { - info->unicode_props0() = (unsigned int) gen_cat | ((info->unicode_props0()) & ~MASK0_GEN_CAT); + info->unicode_props() = (unsigned int) gen_cat | (info->unicode_props() & ~UPROPS_MASK_GEN_CAT); } static inline hb_unicode_general_category_t _hb_glyph_info_get_general_category (const hb_glyph_info_t *info) { - return (hb_unicode_general_category_t) (info->unicode_props0() & MASK0_GEN_CAT); + return (hb_unicode_general_category_t) (info->unicode_props() & UPROPS_MASK_GEN_CAT); } static inline void _hb_glyph_info_set_modified_combining_class (hb_glyph_info_t *info, unsigned int modified_class) { - info->unicode_props1() = modified_class; + info->unicode_props() = (modified_class<<8) | (info->unicode_props() & 0xFF); } static inline unsigned int _hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info) { - return info->unicode_props1(); + return info->unicode_props()>>8; } static inline bool _hb_glyph_info_ligated (const hb_glyph_info_t *info); @@ -265,25 +271,25 @@ static inline bool _hb_glyph_info_ligated (const hb_glyph_info_t *info); static inline hb_bool_t _hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info) { - return (info->unicode_props0() & MASK0_IGNORABLE) && !_hb_glyph_info_ligated (info); + return (info->unicode_props() & UPROPS_MASK_IGNORABLE) && !_hb_glyph_info_ligated (info); } static inline hb_bool_t _hb_glyph_info_is_zwnj (const hb_glyph_info_t *info) { - return !!(info->unicode_props0() & MASK0_ZWNJ); + return !!(info->unicode_props() & UPROPS_MASK_ZWNJ); } static inline hb_bool_t _hb_glyph_info_is_zwj (const hb_glyph_info_t *info) { - return !!(info->unicode_props0() & MASK0_ZWJ); + return !!(info->unicode_props() & UPROPS_MASK_ZWJ); } static inline void _hb_glyph_info_flip_joiners (hb_glyph_info_t *info) { - info->unicode_props0() ^= MASK0_ZWNJ | MASK0_ZWJ; + info->unicode_props() ^= UPROPS_MASK_ZWNJ | UPROPS_MASK_ZWJ; } /* lig_props: aka lig_id / lig_comp @@ -457,22 +463,19 @@ _hb_glyph_info_clear_substituted_and_ligated_and_multiplied (hb_glyph_info_t *in static inline void _hb_buffer_allocate_unicode_vars (hb_buffer_t *buffer) { - HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props0); - HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props1); + HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props); } static inline void _hb_buffer_deallocate_unicode_vars (hb_buffer_t *buffer) { - HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props0); - HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props1); + HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props); } static inline void _hb_buffer_assert_unicode_vars (hb_buffer_t *buffer) { - HB_BUFFER_ASSERT_VAR (buffer, unicode_props0); - HB_BUFFER_ASSERT_VAR (buffer, unicode_props1); + HB_BUFFER_ASSERT_VAR (buffer, unicode_props); } static inline void commit 71277185454482cff9b0c10b85c416eb4d6e0ed9 Author: Behdad Esfahbod <[email protected]> Date: Mon Nov 2 17:27:48 2015 -0800 [perf] Only call combining_class() for marks Saves some time. Also preparing for reusing the ccc byte for other stuff. diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh index d168e27..075a568 100644 --- a/src/hb-ot-layout-private.hh +++ b/src/hb-ot-layout-private.hh @@ -224,12 +224,14 @@ enum { static inline void _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode) { - /* XXX This shouldn't be inlined, or at least not while is_default_ignorable() is inline. */ - info->unicode_props0() = ((unsigned int) unicode->general_category (info->codepoint)) | - (unicode->is_default_ignorable (info->codepoint) ? MASK0_IGNORABLE : 0) | - (info->codepoint == 0x200Cu ? MASK0_ZWNJ : 0) | - (info->codepoint == 0x200Du ? MASK0_ZWJ : 0); - info->unicode_props1() = unicode->modified_combining_class (info->codepoint); + unsigned int gen_cat = (unsigned int) unicode->general_category (info->codepoint); + /* XXX This wouldn't be inlined, or at least not while is_default_ignorable() is inline. */ + info->unicode_props0() = gen_cat | + (unicode->is_default_ignorable (info->codepoint) ? MASK0_IGNORABLE : 0) | + (info->codepoint == 0x200Cu ? MASK0_ZWNJ : 0) | + (info->codepoint == 0x200Du ? MASK0_ZWJ : 0); + info->unicode_props1() = unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (gen_cat)) ? + unicode->modified_combining_class (info->codepoint) : 0; } static inline void _______________________________________________ HarfBuzz mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/harfbuzz
