diff options
author | jshin@chromium.org <jshin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-12 19:41:39 +0000 |
---|---|---|
committer | jshin@chromium.org <jshin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-12 19:41:39 +0000 |
commit | 3be69d193c79756c13f654f9e507cfc598943309 (patch) | |
tree | 9799e5ed4e44e8a7f47c6f5e25767a4299bffe5a /third_party | |
parent | eac231599d20cd771cbb73eac54b6ce5f1946df8 (diff) | |
download | chromium_src-3be69d193c79756c13f654f9e507cfc598943309.zip chromium_src-3be69d193c79756c13f654f9e507cfc598943309.tar.gz chromium_src-3be69d193c79756c13f654f9e507cfc598943309.tar.bz2 |
Update harfbuzz-ng to 0.9.17
Changes include
- major speed up, especially in Arabic
- Critical bug fixes in Arabic shaping
TBR=darin
BUG=236442
TEST=Build goes through and all the existing layout test pass.
Review URL: https://codereview.chromium.org/16053004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@205896 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party')
32 files changed, 335 insertions, 361 deletions
diff --git a/third_party/harfbuzz-ng/COPYING b/third_party/harfbuzz-ng/COPYING index 4bb77a0..9d1056f 100644 --- a/third_party/harfbuzz-ng/COPYING +++ b/third_party/harfbuzz-ng/COPYING @@ -1,11 +1,16 @@ HarfBuzz is licensed under the so-called "Old MIT" license. Details follow. +For parts of HarfBuzz that are licensed under different licenses see individual +files names COPYING in subdirectories where applicable. -Copyright © 2011 Codethink Limited -Copyright © 2010,2011 Google, Inc. -Copyright © 2006 Behdad Esfahbod +Copyright © 2010,2011,2012 Google, Inc. +Copyright © 2012 Mozilla Foundation +Copyright © 2011 Codethink Limited +Copyright © 2008,2010 Nokia Corporation and/or its subsidiary(-ies) Copyright © 2009 Keith Stribley Copyright © 2009 Martin Hosken and SIL International Copyright © 2007 Chris Wilson +Copyright © 2006 Behdad Esfahbod +Copyright © 2005 David Turner Copyright © 2004,2007,2008,2009,2010 Red Hat, Inc. Copyright © 1998-2004 David Turner and Werner Lemberg diff --git a/third_party/harfbuzz-ng/NEWS b/third_party/harfbuzz-ng/NEWS index 858a916..600e6cd 100644 --- a/third_party/harfbuzz-ng/NEWS +++ b/third_party/harfbuzz-ng/NEWS @@ -1,3 +1,32 @@ +Overview of changes leading to 0.9.17 +Monday, May 20, 2013 +===================================== + +- Build fixes. +- Fix bug in hb_set_get_min(). +- Fix regression with Arabic mark positioning / width-zeroing. + +Overview of changes leading to 0.9.16 +Friday, April 19, 2013 +===================================== + +- Major speedup in OpenType lookup processing. With the Amiri + Arabic font, this release is over 3x faster than previous + release. All scripts / languages should see this speedup. + +- New --num-iterations option for hb-shape / hb-view; useful for + profiling. + +Overview of changes leading to 0.9.15 +Friday, April 05, 2013 +===================================== + +- Build fixes. +- Fix crasher in graphite2 shaper. +- Fix Arabic mark width zeroing regression. +- Don't compose Hangul jamo into Unicode syllables. + + Overview of changes leading to 0.9.14 Thursday, March 21, 2013 ===================================== diff --git a/third_party/harfbuzz-ng/README.chromium b/third_party/harfbuzz-ng/README.chromium index b70e893..ad2f1a5 100644 --- a/third_party/harfbuzz-ng/README.chromium +++ b/third_party/harfbuzz-ng/README.chromium @@ -1,9 +1,8 @@ Name: harfbuzz-ng Short Name: harfbuzz-ng -URL: http://freedesktop.org/wiki/Software/HarfBuzz -Version: 0.9.14 -Date: 20130321 -Revision: f872a17462a75a3493623747bf3a3fbe54556c7b +URL: http://harfbuzz.org +Version: 0.9.17 +Date: 20130520 Security Critical: yes License: MIT License File: COPYING @@ -25,4 +24,4 @@ In addition, all unneeded files from the root directory and src/ directory (hb-icu-le, hb-ucdn, hb-old, scripts to generate data tables, automake/conf files) are deleted. -_POSIX_C_SOURCE is undefined in src/hb-blob.cc before (re)defining it. +Besides, _POSIX_C_SOURCE is undefined in src/hb-blob.cc before (re)defining it. diff --git a/third_party/harfbuzz-ng/harfbuzz.gyp b/third_party/harfbuzz-ng/harfbuzz.gyp index da7bc2f..c04b503 100644 --- a/third_party/harfbuzz-ng/harfbuzz.gyp +++ b/third_party/harfbuzz-ng/harfbuzz.gyp @@ -60,7 +60,6 @@ 'src/hb-ot-shape-complex-indic-machine.hh', 'src/hb-ot-shape-complex-indic-private.hh', 'src/hb-ot-shape-complex-indic-table.cc', - 'src/hb-ot-shape-complex-indic-table.hh', 'src/hb-ot-shape-complex-indic.cc', 'src/hb-ot-shape-complex-myanmar-machine.hh', 'src/hb-ot-shape-complex-myanmar.cc', diff --git a/third_party/harfbuzz-ng/src/hb-atomic-private.hh b/third_party/harfbuzz-ng/src/hb-atomic-private.hh index 7047e21..9cc3bc5 100644 --- a/third_party/harfbuzz-ng/src/hb-atomic-private.hh +++ b/third_party/harfbuzz-ng/src/hb-atomic-private.hh @@ -47,6 +47,14 @@ #define WIN32_LEAN_AND_MEAN #include <windows.h> +#if defined(__MINGW32__) && !defined(MemoryBarrier) +static inline void _HBMemoryBarrier (void) { + long dummy = 0; + InterlockedExchange (&dummy, 1); +} +# define MemoryBarrier _HBMemoryBarrier +#endif + typedef LONG hb_atomic_int_t; #define hb_atomic_int_add(AI, V) InterlockedExchangeAdd (&(AI), (V)) diff --git a/third_party/harfbuzz-ng/src/hb-buffer-private.hh b/third_party/harfbuzz-ng/src/hb-buffer-private.hh index 387ebd9..a8cf770 100644 --- a/third_party/harfbuzz-ng/src/hb-buffer-private.hh +++ b/third_party/harfbuzz-ng/src/hb-buffer-private.hh @@ -80,6 +80,8 @@ struct hb_buffer_t { inline hb_glyph_info_t &prev (void) { return out_info[out_len - 1]; } inline hb_glyph_info_t prev (void) const { return info[out_len - 1]; } + inline bool has_separate_output (void) const { return info != out_info; } + unsigned int serial; /* These reflect current allocations of the bytes in glyph_info_t's var1 and var2. */ diff --git a/third_party/harfbuzz-ng/src/hb-buffer.cc b/third_party/harfbuzz-ng/src/hb-buffer.cc index 4e26250..c0ca484 100644 --- a/third_party/harfbuzz-ng/src/hb-buffer.cc +++ b/third_party/harfbuzz-ng/src/hb-buffer.cc @@ -549,7 +549,7 @@ void hb_buffer_t::allocate_var (unsigned int byte_i, unsigned int count, const c { assert (byte_i < 8 && byte_i + count <= 8); - if (DEBUG (BUFFER)) + if (DEBUG_ENABLED (BUFFER)) dump_var_allocation (this); DEBUG_MSG (BUFFER, this, "Allocating var bytes %d..%d for %s", @@ -564,7 +564,7 @@ void hb_buffer_t::allocate_var (unsigned int byte_i, unsigned int count, const c void hb_buffer_t::deallocate_var (unsigned int byte_i, unsigned int count, const char *owner) { - if (DEBUG (BUFFER)) + if (DEBUG_ENABLED (BUFFER)) dump_var_allocation (this); DEBUG_MSG (BUFFER, this, @@ -581,7 +581,7 @@ void hb_buffer_t::deallocate_var (unsigned int byte_i, unsigned int count, const void hb_buffer_t::assert_var (unsigned int byte_i, unsigned int count, const char *owner) { - if (DEBUG (BUFFER)) + if (DEBUG_ENABLED (BUFFER)) dump_var_allocation (this); DEBUG_MSG (BUFFER, this, diff --git a/third_party/harfbuzz-ng/src/hb-graphite2.cc b/third_party/harfbuzz-ng/src/hb-graphite2.cc index 16ef9a4..cce8606 100644 --- a/third_party/harfbuzz-ng/src/hb-graphite2.cc +++ b/third_party/harfbuzz-ng/src/hb-graphite2.cc @@ -226,7 +226,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan, gr_font *grfont = HB_SHAPER_DATA_GET (font); const char *lang = hb_language_to_string (hb_buffer_get_language (buffer)); - const char *lang_end = strchr (lang, '-'); + const char *lang_end = lang ? strchr (lang, '-') : NULL; int lang_len = lang_end ? lang_end - lang : -1; gr_feature_val *feats = gr_face_featureval_for_lang (grface, lang ? hb_tag_from_string (lang, lang_len) : 0); diff --git a/third_party/harfbuzz-ng/src/hb-open-type-private.hh b/third_party/harfbuzz-ng/src/hb-open-type-private.hh index cd1163e..6a8b98b 100644 --- a/third_party/harfbuzz-ng/src/hb-open-type-private.hh +++ b/third_party/harfbuzz-ng/src/hb-open-type-private.hh @@ -949,21 +949,22 @@ template <typename Type> struct SortedArrayOf : ArrayOf<Type> { template <typename SearchType> - inline int search (const SearchType &x) const { - unsigned int count = this->len; - /* Linear search is *much* faster for small counts. */ - if (likely (count < 32)) { - for (unsigned int i = 0; i < count; i++) - if (this->array[i].cmp (x) == 0) - return i; - return -1; - } else { - struct Cmp { - static int cmp (const SearchType *a, const Type *b) { return b->cmp (*a); } - }; - const Type *p = (const Type *) bsearch (&x, this->array, this->len, sizeof (this->array[0]), (hb_compare_func_t) Cmp::cmp); - return p ? p - this->array : -1; + inline int search (const SearchType &x) const + { + /* Hand-coded bsearch here since this is in the hot inner loop. */ + int min = 0, max = (int) this->len - 1; + while (min <= max) + { + int mid = (min + max) / 2; + int c = this->array[mid].cmp (x); + if (c < 0) + max = mid - 1; + else if (c > 0) + min = mid + 1; + else + return mid; } + return -1; } }; diff --git a/third_party/harfbuzz-ng/src/hb-ot-layout-common-private.hh b/third_party/harfbuzz-ng/src/hb-ot-layout-common-private.hh index e6018db..d139b56 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-layout-common-private.hh +++ b/third_party/harfbuzz-ng/src/hb-ot-layout-common-private.hh @@ -129,8 +129,7 @@ struct RecordListOf : RecordArrayOf<Type> struct RangeRecord { inline int cmp (hb_codepoint_t g) const { - hb_codepoint_t a = start, b = end; - return g < a ? -1 : g <= b ? 0 : +1 ; + return g < start ? -1 : g <= end ? 0 : +1 ; } inline bool sanitize (hb_sanitize_context_t *c) { diff --git a/third_party/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh b/third_party/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh index 4413927..56b3a4f 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh +++ b/third_party/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh @@ -710,8 +710,6 @@ struct PairPosFormat2 TRACE_COLLECT_GLYPHS (this); /* (this+coverage).add_coverage (c->input); // Don't need this. */ - /* TODO only add values for pairs that have nonzero adjustments. */ - unsigned int count1 = class1Count; const ClassDef &klass1 = this+classDef1; for (unsigned int i = 0; i < count1; i++) @@ -1014,7 +1012,6 @@ struct MarkBasePosFormat1 TRACE_COLLECT_GLYPHS (this); (this+markCoverage).add_coverage (c->input); (this+baseCoverage).add_coverage (c->input); - /* TODO only add combinations that have nonzero adjustment. */ } inline const Coverage &get_coverage (void) const @@ -1118,7 +1115,6 @@ struct MarkLigPosFormat1 TRACE_COLLECT_GLYPHS (this); (this+markCoverage).add_coverage (c->input); (this+ligatureCoverage).add_coverage (c->input); - /* TODO only add combinations that have nonzero adjustment. */ } inline const Coverage &get_coverage (void) const @@ -1234,7 +1230,6 @@ struct MarkMarkPosFormat1 TRACE_COLLECT_GLYPHS (this); (this+mark1Coverage).add_coverage (c->input); (this+mark2Coverage).add_coverage (c->input); - /* TODO only add combinations that have nonzero adjustment. */ } inline const Coverage &get_coverage (void) const @@ -1480,8 +1475,8 @@ struct PosLookup : Lookup while (c->buffer->idx < c->buffer->len) { - if ((c->buffer->cur().mask & c->lookup_mask) && - digest->may_have (c->buffer->cur().codepoint) && + if (digest->may_have (c->buffer->cur().codepoint) && + (c->buffer->cur().mask & c->lookup_mask) && apply_once (c)) ret = true; else diff --git a/third_party/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh b/third_party/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh index 35d0729..3b6635b 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh +++ b/third_party/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh @@ -275,11 +275,18 @@ struct Sequence unsigned int klass = c->buffer->cur().glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE ? HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0; unsigned int count = substitute.len; - for (unsigned int i = 0; i < count; i++) { - set_lig_props_for_component (c->buffer->cur(), i); - c->output_glyph (substitute.array[i], klass); + if (count == 1) /* Special-case to make it in-place. */ + { + c->replace_glyph (substitute.array[0]); + } + else + { + for (unsigned int i = 0; i < count; i++) { + set_lig_props_for_component (c->buffer->cur(), i); + c->output_glyph (substitute.array[i], klass); + } + c->buffer->skip_glyph (); } - c->buffer->skip_glyph (); return TRACE_RETURN (true); } @@ -1196,38 +1203,38 @@ struct SubstLookup : Lookup if (likely (!is_reverse ())) { - /* in/out forward substitution */ - c->buffer->clear_output (); - c->buffer->idx = 0; - - while (c->buffer->idx < c->buffer->len) - { - if ((c->buffer->cur().mask & c->lookup_mask) && - digest->may_have (c->buffer->cur().codepoint) && - apply_once (c)) - ret = true; - else - c->buffer->next_glyph (); - } - if (ret) - c->buffer->swap_buffers (); + /* in/out forward substitution */ + c->buffer->clear_output (); + c->buffer->idx = 0; + + while (c->buffer->idx < c->buffer->len) + { + if (digest->may_have (c->buffer->cur().codepoint) && + (c->buffer->cur().mask & c->lookup_mask) && + apply_once (c)) + ret = true; + else + c->buffer->next_glyph (); + } + if (ret) + c->buffer->swap_buffers (); } else { - /* in-place backward substitution */ - c->buffer->remove_output (); - c->buffer->idx = c->buffer->len - 1; - do - { - if ((c->buffer->cur().mask & c->lookup_mask) && - digest->may_have (c->buffer->cur().codepoint) && - apply_once (c)) - ret = true; - else - c->buffer->idx--; + /* in-place backward substitution */ + c->buffer->remove_output (); + c->buffer->idx = c->buffer->len - 1; + do + { + if (digest->may_have (c->buffer->cur().codepoint) && + (c->buffer->cur().mask & c->lookup_mask) && + apply_once (c)) + ret = true; + else + c->buffer->idx--; - } - while ((int) c->buffer->idx >= 0); + } + while ((int) c->buffer->idx >= 0); } return ret; diff --git a/third_party/harfbuzz-ng/src/hb-ot-layout.cc b/third_party/harfbuzz-ng/src/hb-ot-layout.cc index 8161ce3d..c80ca7d 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-layout.cc +++ b/third_party/harfbuzz-ng/src/hb-ot-layout.cc @@ -70,9 +70,15 @@ _hb_ot_layout_create (hb_face_t *face) } for (unsigned int i = 0; i < layout->gsub_lookup_count; i++) + { + layout->gsub_digests[i].init (); layout->gsub->get_lookup (i).add_coverage (&layout->gsub_digests[i]); + } for (unsigned int i = 0; i < layout->gpos_lookup_count; i++) + { + layout->gpos_digests[i].init (); layout->gpos->get_lookup (i).add_coverage (&layout->gpos_digests[i]); + } return layout; } diff --git a/third_party/harfbuzz-ng/src/hb-ot-map-private.hh b/third_party/harfbuzz-ng/src/hb-ot-map-private.hh index a679fb5..5ed54a6 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-map-private.hh +++ b/third_party/harfbuzz-ng/src/hb-ot-map-private.hh @@ -1,6 +1,6 @@ /* * Copyright © 2009,2010 Red Hat, Inc. - * Copyright © 2010,2011,2012 Google, Inc. + * Copyright © 2010,2011,2012,2013 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -31,8 +31,8 @@ #include "hb-buffer-private.hh" -#include "hb-ot-layout-private.hh" +struct hb_ot_shape_plan_t; static const hb_tag_t table_tags[2] = {HB_OT_TAG_GSUB, HB_OT_TAG_GPOS}; @@ -67,9 +67,9 @@ struct hb_ot_map_t typedef void (*pause_func_t) (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); - struct pause_map_t { - unsigned int num_lookups; /* Cumulative */ - pause_func_t callback; + struct stage_map_t { + unsigned int last_lookup; /* Cumulative */ + pause_func_t pause_func; }; @@ -110,23 +110,28 @@ struct hb_ot_map_t *lookup_count = 0; return; } - assert (stage <= pauses[table_index].len); - unsigned int start = stage ? pauses[table_index][stage - 1].num_lookups : 0; - unsigned int end = stage < pauses[table_index].len ? pauses[table_index][stage].num_lookups : lookups[table_index].len; + assert (stage <= stages[table_index].len); + unsigned int start = stage ? stages[table_index][stage - 1].last_lookup : 0; + unsigned int end = stage < stages[table_index].len ? stages[table_index][stage].last_lookup : lookups[table_index].len; *plookups = &lookups[table_index][start]; *lookup_count = end - start; } HB_INTERNAL void collect_lookups (unsigned int table_index, hb_set_t *lookups) const; + HB_INTERNAL inline void apply (unsigned int table_index, + const struct hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer) const; HB_INTERNAL void substitute (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const; HB_INTERNAL void position (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const; inline void finish (void) { features.finish (); - lookups[0].finish (); - lookups[1].finish (); - pauses[0].finish (); - pauses[1].finish (); + for (unsigned int table_index = 0; table_index < 2; table_index++) + { + lookups[table_index].finish (); + stages[table_index].finish (); + } } public: @@ -145,7 +150,7 @@ struct hb_ot_map_t hb_prealloced_array_t<feature_map_t, 8> features; hb_prealloced_array_t<lookup_map_t, 32> lookups[2]; /* GSUB/GPOS */ - hb_prealloced_array_t<pause_map_t, 1> pauses[2]; /* GSUB/GPOS */ + hb_prealloced_array_t<stage_map_t, 4> stages[2]; /* GSUB/GPOS */ }; enum hb_ot_map_feature_flags_t { @@ -195,8 +200,10 @@ struct hb_ot_map_builder_t inline void finish (void) { feature_infos.finish (); - pauses[0].finish (); - pauses[1].finish (); + for (unsigned int table_index = 0; table_index < 2; table_index++) + { + stages[table_index].finish (); + } } private: @@ -213,9 +220,9 @@ struct hb_ot_map_builder_t { return (a->tag != b->tag) ? (a->tag < b->tag ? -1 : 1) : (a->seq < b->seq ? -1 : 1); } }; - struct pause_info_t { - unsigned int stage; - hb_ot_map_t::pause_func_t callback; + struct stage_info_t { + unsigned int index; + hb_ot_map_t::pause_func_t pause_func; }; HB_INTERNAL void add_pause (unsigned int table_index, hb_ot_map_t::pause_func_t pause_func); @@ -232,8 +239,8 @@ struct hb_ot_map_builder_t private: unsigned int current_stage[2]; /* GSUB/GPOS */ - hb_prealloced_array_t<feature_info_t,16> feature_infos; - hb_prealloced_array_t<pause_info_t, 1> pauses[2]; /* GSUB/GPOS */ + hb_prealloced_array_t<feature_info_t, 32> feature_infos; + hb_prealloced_array_t<stage_info_t, 8> stages[2]; /* GSUB/GPOS */ }; diff --git a/third_party/harfbuzz-ng/src/hb-ot-map.cc b/third_party/harfbuzz-ng/src/hb-ot-map.cc index 85e6e16..dd26afc 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-map.cc +++ b/third_party/harfbuzz-ng/src/hb-ot-map.cc @@ -1,6 +1,6 @@ /* * Copyright © 2009,2010 Red Hat, Inc. - * Copyright © 2010,2011 Google, Inc. + * Copyright © 2010,2011,2013 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -28,6 +28,8 @@ #include "hb-ot-map-private.hh" +#include "hb-ot-layout-private.hh" + void hb_ot_map_t::add_lookups (hb_face_t *face, @@ -100,55 +102,50 @@ void hb_ot_map_builder_t::add_feature (hb_tag_t tag, unsigned int value, info->stage[1] = current_stage[1]; } -/* Keep the next two functions in sync. */ - -void hb_ot_map_t::substitute (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const +inline void hb_ot_map_t::apply (unsigned int table_index, + const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer) const { - const unsigned int table_index = 0; unsigned int i = 0; - for (unsigned int pause_index = 0; pause_index < pauses[table_index].len; pause_index++) { - const pause_map_t *pause = &pauses[table_index][pause_index]; - for (; i < pause->num_lookups; i++) - hb_ot_layout_substitute_lookup (font, buffer, - lookups[table_index][i].index, - lookups[table_index][i].mask, - lookups[table_index][i].auto_zwj); - - buffer->clear_output (); + for (unsigned int stage_index = 0; stage_index < stages[table_index].len; stage_index++) { + const stage_map_t *stage = &stages[table_index][stage_index]; + for (; i < stage->last_lookup; i++) + switch (table_index) + { + case 0: + hb_ot_layout_substitute_lookup (font, buffer, lookups[table_index][i].index, + lookups[table_index][i].mask, + lookups[table_index][i].auto_zwj); + break; + + case 1: + hb_ot_layout_position_lookup (font, buffer, lookups[table_index][i].index, + lookups[table_index][i].mask, + lookups[table_index][i].auto_zwj); + break; + } - if (pause->callback) - pause->callback (plan, font, buffer); + if (stage->pause_func) + { + buffer->clear_output (); + stage->pause_func (plan, font, buffer); + } } +} - for (; i < lookups[table_index].len; i++) - hb_ot_layout_substitute_lookup (font, buffer, lookups[table_index][i].index, - lookups[table_index][i].mask, - lookups[table_index][i].auto_zwj); +void hb_ot_map_t::substitute (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const +{ + apply (0, plan, font, buffer); } void hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const { - const unsigned int table_index = 1; - unsigned int i = 0; - - for (unsigned int pause_index = 0; pause_index < pauses[table_index].len; pause_index++) { - const pause_map_t *pause = &pauses[table_index][pause_index]; - for (; i < pause->num_lookups; i++) - hb_ot_layout_position_lookup (font, buffer, lookups[table_index][i].index, - lookups[table_index][i].mask, - lookups[table_index][i].auto_zwj); - - if (pause->callback) - pause->callback (plan, font, buffer); - } - - for (; i < lookups[table_index].len; i++) - hb_ot_layout_position_lookup (font, buffer, lookups[table_index][i].index, - lookups[table_index][i].mask, - lookups[table_index][i].auto_zwj); + apply (1, plan, font, buffer); } + void hb_ot_map_t::collect_lookups (unsigned int table_index, hb_set_t *lookups_out) const { for (unsigned int i = 0; i < lookups[table_index].len; i++) @@ -157,10 +154,10 @@ void hb_ot_map_t::collect_lookups (unsigned int table_index, hb_set_t *lookups_o void hb_ot_map_builder_t::add_pause (unsigned int table_index, hb_ot_map_t::pause_func_t pause_func) { - pause_info_t *p = pauses[table_index].push (); - if (likely (p)) { - p->stage = current_stage[table_index]; - p->callback = pause_func; + stage_info_t *s = stages[table_index].push (); + if (likely (s)) { + s->index = current_stage[table_index]; + s->pause_func = pause_func; } current_stage[table_index]++; @@ -277,7 +274,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m) &required_feature_index)) m.add_lookups (face, table_index, required_feature_index, 1, true); - unsigned int pause_index = 0; + unsigned int stage_index = 0; unsigned int last_num_lookups = 0; for (unsigned stage = 0; stage < current_stage[table_index]; stage++) { @@ -307,14 +304,14 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m) last_num_lookups = m.lookups[table_index].len; - if (pause_index < pauses[table_index].len && pauses[table_index][pause_index].stage == stage) { - hb_ot_map_t::pause_map_t *pause_map = m.pauses[table_index].push (); - if (likely (pause_map)) { - pause_map->num_lookups = last_num_lookups; - pause_map->callback = pauses[table_index][pause_index].callback; + if (stage_index < stages[table_index].len && stages[table_index][stage_index].index == stage) { + hb_ot_map_t::stage_map_t *stage_map = m.stages[table_index].push (); + if (likely (stage_map)) { + stage_map->last_lookup = last_num_lookups; + stage_map->pause_func = stages[table_index][stage_index].pause_func; } - pause_index++; + stage_index++; } } } diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh index 5e151f7..996e40e 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh +++ b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh @@ -212,7 +212,9 @@ arabic_fallback_plan_create (const hb_ot_shape_plan_t *plan, if (unlikely (!fallback_plan)) return const_cast<arabic_fallback_plan_t *> (&arabic_fallback_plan_nil); - for (unsigned int i = 0; i < ARABIC_NUM_FALLBACK_FEATURES; i++) { + for (unsigned int i = 0; i < ARABIC_NUM_FALLBACK_FEATURES; i++) + { + fallback_plan->digest_array[i].init (); fallback_plan->mask_array[i] = plan->map.get_1_mask (arabic_fallback_features[i]); if (fallback_plan->mask_array[i]) { fallback_plan->lookup_array[i] = arabic_fallback_synthesize_lookup (plan, font, i); diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc index 18b3d02..7f8778a 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc +++ b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc @@ -352,6 +352,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic = NULL, /* decompose */ NULL, /* compose */ setup_masks_arabic, - HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE, + HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, true, /* fallback_position */ }; diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-default.cc b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-default.cc index fad57f6..d6afa0e 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-default.cc +++ b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-default.cc @@ -74,12 +74,6 @@ collect_features_default (hb_ot_shape_planner_t *plan) static hb_ot_shape_normalization_mode_t normalization_preference_default (const hb_segment_properties_t *props) { - switch ((hb_tag_t) props->script) - { - /* Unicode-1.1 additions */ - case HB_SCRIPT_HANGUL: - return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_FULL; - } return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS; } @@ -221,6 +215,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default = NULL, /* decompose */ compose_default, NULL, /* setup_masks */ - HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE, + HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE, true, /* fallback_position */ }; diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.rl b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.rl deleted file mode 100644 index f9f07d8..0000000 --- a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.rl +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright © 2011,2012 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_SHAPE_COMPLEX_INDIC_MACHINE_HH -#define HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH - -#include "hb-private.hh" - -%%{ - machine indic_syllable_machine; - alphtype unsigned char; - write data; -}%% - -%%{ - -# Same order as enum indic_category_t. Not sure how to avoid duplication. -X = 0; -C = 1; -V = 2; -N = 3; -H = 4; -ZWNJ = 5; -ZWJ = 6; -M = 7; -SM = 8; -VD = 9; -A = 10; -NBSP = 11; -DOTTEDCIRCLE = 12; -RS = 13; -Coeng = 14; -Repha = 15; -Ra = 16; -CM = 17; - -c = (C | Ra)CM*; # is_consonant -n = ((ZWNJ?.RS)? (N.N?)?); # is_consonant_modifier -z = ZWJ|ZWNJ; # is_joiner -h = H | Coeng; # is_halant_or_coeng -reph = (Ra H | Repha); # possible reph - -cn = c.ZWJ?.n?; -forced_rakar = ZWJ H ZWJ Ra; -matra_group = z{0,3}.M.N?.(H | forced_rakar)?; -syllable_tail = (Coeng (cn|V))? (SM.ZWNJ?)? (VD VD?)?; -place_holder = NBSP | DOTTEDCIRCLE; -halant_group = (z?.h.(ZWJ.N?)?); -final_halant_group = halant_group | h.ZWNJ; -halant_or_matra_group = (final_halant_group | (h.ZWJ)? matra_group{0,4}); - - -consonant_syllable = Repha? (cn.halant_group){0,4} cn A? halant_or_matra_group? syllable_tail; -vowel_syllable = reph? V.n? (ZWJ | (halant_group.cn){0,4} halant_or_matra_group? syllable_tail); -standalone_cluster = reph? place_holder.n? (halant_group.cn){0,4} halant_or_matra_group? syllable_tail; -broken_cluster = reph? n? (halant_group.cn){0,4} halant_or_matra_group syllable_tail; -other = any; - -main := |* - consonant_syllable => { found_syllable (consonant_syllable); }; - vowel_syllable => { found_syllable (vowel_syllable); }; - standalone_cluster => { found_syllable (standalone_cluster); }; - broken_cluster => { found_syllable (broken_cluster); }; - other => { found_syllable (non_indic_cluster); }; -*|; - - -}%% - -#define found_syllable(syllable_type) \ - HB_STMT_START { \ - if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \ - for (unsigned int i = last; i < p+1; i++) \ - info[i].syllable() = (syllable_serial << 4) | syllable_type; \ - last = p+1; \ - syllable_serial++; \ - if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ - } HB_STMT_END - -static void -find_syllables (hb_buffer_t *buffer) -{ - unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED; - int cs; - hb_glyph_info_t *info = buffer->info; - %%{ - write init; - getkey info[p].indic_category(); - }%% - - p = 0; - pe = eof = buffer->len; - - unsigned int last = 0; - unsigned int syllable_serial = 1; - %%{ - write exec; - }%% -} - -#endif /* HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH */ diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc index ff13bdd..e5af893 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc +++ b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc @@ -540,6 +540,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar = NULL, /* decompose */ NULL, /* compose */ setup_masks_myanmar, - HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF, + HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY, false, /* fallback_position */ }; diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-private.hh b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-private.hh index 3c9922d..62151ba 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-private.hh +++ b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-private.hh @@ -41,8 +41,10 @@ enum hb_ot_shape_zero_width_marks_type_t { HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, - HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE, - HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF +// HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY, + HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE, + HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY, + HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE }; @@ -185,6 +187,20 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) return &_hb_ot_complex_shaper_thai; +#if 0 + /* Note: + * Currently we don't have a separate Hangul shaper. The default shaper handles + * Hangul by enabling jamo features. We may want to implement a separate shaper + * in the future. See this thread for details of what such a shaper would do: + * + * http://lists.freedesktop.org/archives/harfbuzz/2013-April/003070.html + */ + /* Unicode-1.1 additions */ + case HB_SCRIPT_HANGUL: + + return &_hb_ot_complex_shaper_hangul; +#endif + /* ^--- Add new shapers here */ diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc index 5cbb6e3..4594533 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc +++ b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc @@ -373,6 +373,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_thai = NULL, /* decompose */ NULL, /* compose */ NULL, /* setup_masks */ - HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE, + HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE, false,/* fallback_position */ }; diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh b/third_party/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh index 8112f03..085d485 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh +++ b/third_party/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh @@ -41,7 +41,6 @@ enum hb_ot_shape_normalization_mode_t { HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED, HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS, /* never composes base-to-base */ HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, /* always fully decomposes and then recompose back */ - HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_FULL, /* including base-to-base composition */ HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT = HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS }; diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-normalize.cc b/third_party/harfbuzz-ng/src/hb-ot-shape-normalize.cc index 344c0ff..7f83d9d 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-shape-normalize.cc +++ b/third_party/harfbuzz-ng/src/hb-ot-shape-normalize.cc @@ -170,7 +170,7 @@ decompose (const hb_ot_shape_normalize_context_t *c, bool shortest, hb_codepoint } /* Returns 0 if didn't decompose, number of resulting characters otherwise. */ -static inline bool +static inline unsigned int decompose_compatibility (const hb_ot_shape_normalize_context_t *c, hb_codepoint_t u) { unsigned int len, i; @@ -191,7 +191,6 @@ decompose_compatibility (const hb_ot_shape_normalize_context_t *c, hb_codepoint_ return len; } -/* Returns true if recomposition may be benefitial. */ static inline void decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shortest) { @@ -231,7 +230,6 @@ handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, uns } } -/* Returns true if recomposition may be benefitial. */ static inline void decompose_multi_char_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end) { @@ -353,12 +351,11 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, while (buffer->idx < count) { hb_codepoint_t composed, glyph; - if (/* If mode is NOT COMPOSED_FULL (ie. it's COMPOSED_DIACRITICS), we don't try to - * compose a non-mark character with it's preceding starter. This is just an - * optimization to avoid trying to compose every two neighboring glyphs in most - * scripts. */ - (mode == HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_FULL || - HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->cur()))) && + if (/* We don't try to compose a non-mark character with it's preceding starter. + * This is both an optimization to avoid trying to compose every two neighboring + * glyphs in most scripts AND a desired feature for Hangul. Apparently Hangul + * fonts are not designed to mix-and-match pre-composed syllables and Jamo. */ + HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->cur())) && /* If there's anything between the starter and this char, they should have CCC * smaller than this character's. */ (starter == buffer->out_len - 1 || diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-private.hh b/third_party/harfbuzz-ng/src/hb-ot-shape-private.hh index 9599f8e..8171471 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-shape-private.hh +++ b/third_party/harfbuzz-ng/src/hb-ot-shape-private.hh @@ -30,8 +30,7 @@ #include "hb-private.hh" #include "hb-ot-map-private.hh" - - +#include "hb-ot-layout-private.hh" diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape.cc b/third_party/harfbuzz-ng/src/hb-ot-shape.cc index f65861f..6a0c786 100644 --- a/third_party/harfbuzz-ng/src/hb-ot-shape.cc +++ b/third_party/harfbuzz-ng/src/hb-ot-shape.cc @@ -401,6 +401,30 @@ hb_ot_substitute (hb_ot_shape_context_t *c) /* Position */ static inline void +zero_mark_widths_by_unicode (hb_buffer_t *buffer) +{ + unsigned int count = buffer->len; + for (unsigned int i = 0; i < count; i++) + if (_hb_glyph_info_get_general_category (&buffer->info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) + { + buffer->pos[i].x_advance = 0; + buffer->pos[i].y_advance = 0; + } +} + +static inline void +zero_mark_widths_by_gdef (hb_buffer_t *buffer) +{ + unsigned int count = buffer->len; + for (unsigned int i = 0; i < count; i++) + if ((buffer->info[i].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK)) + { + buffer->pos[i].x_advance = 0; + buffer->pos[i].y_advance = 0; + } +} + +static inline void hb_ot_position_default (hb_ot_shape_context_t *c) { hb_ot_layout_position_start (c->font, c->buffer); @@ -419,22 +443,22 @@ hb_ot_position_default (hb_ot_shape_context_t *c) } - /* Zero'ing mark widths by GDEF (as used in Myanmar spec) happens - * *before* GPOS. */ switch (c->plan->shaper->zero_width_marks) { - case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF: - for (unsigned int i = 0; i < count; i++) - if ((c->buffer->info[i].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK)) - { - c->buffer->pos[i].x_advance = 0; - c->buffer->pos[i].y_advance = 0; - } + case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: + zero_mark_widths_by_gdef (c->buffer); + break; + + /* Not currently used for any shaper: + case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY: + zero_mark_widths_by_unicode (c->buffer); break; + */ default: case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: - case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE: + case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE: + case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: break; } } @@ -468,22 +492,20 @@ hb_ot_position_complex (hb_ot_shape_context_t *c) ret = true; } - /* Zero'ing mark widths by Unicode happens - * *after* GPOS. */ switch (c->plan->shaper->zero_width_marks) { - case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE: - for (unsigned int i = 0; i < count; i++) - if (_hb_glyph_info_get_general_category (&c->buffer->info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) - { - c->buffer->pos[i].x_advance = 0; - c->buffer->pos[i].y_advance = 0; - } + case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE: + zero_mark_widths_by_unicode (c->buffer); + break; + + case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: + zero_mark_widths_by_gdef (c->buffer); break; default: case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: - case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF: + //case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY: + case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: break; } diff --git a/third_party/harfbuzz-ng/src/hb-private.hh b/third_party/harfbuzz-ng/src/hb-private.hh index ff1e85d..8121640 100644 --- a/third_party/harfbuzz-ng/src/hb-private.hh +++ b/third_party/harfbuzz-ng/src/hb-private.hh @@ -517,7 +517,7 @@ static inline uint32_t hb_uint32_swap (const uint32_t v) #define hb_be_uint32_get(v) (uint32_t) ((v[0] << 24) + (v[1] << 16) + (v[2] << 8) + v[3]) #define hb_be_uint32_eq(a,b) (a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && a[3] == b[3]) -#define hb_be_uint24_put(v,V) HB_STMT_START { v[0] = (V>>16); v[1] = (V>>8); v[2] (V); } HB_STMT_END +#define hb_be_uint24_put(v,V) HB_STMT_START { v[0] = (V>>16); v[1] = (V>>8); v[2] = (V); } HB_STMT_END #define hb_be_uint24_get(v) (uint32_t) ((v[0] << 16) + (v[1] << 8) + v[2]) #define hb_be_uint24_eq(a,b) (a[0] == b[0] && a[1] == b[1] && a[2] == b[2]) @@ -563,8 +563,8 @@ _hb_debug (unsigned int level, return level < max_level; } -#define DEBUG_LEVEL(WHAT, LEVEL) (_hb_debug ((LEVEL), HB_DEBUG_##WHAT)) -#define DEBUG(WHAT) (DEBUG_LEVEL (WHAT, 0)) +#define DEBUG_LEVEL_ENABLED(WHAT, LEVEL) (_hb_debug ((LEVEL), HB_DEBUG_##WHAT)) +#define DEBUG_ENABLED(WHAT) (DEBUG_LEVEL_ENABLED (WHAT, 0)) template <int max_level> static inline void _hb_debug_msg_va (const char *what, diff --git a/third_party/harfbuzz-ng/src/hb-set-private.hh b/third_party/harfbuzz-ng/src/hb-set-private.hh index 5e30a7e..adfa88f 100644 --- a/third_party/harfbuzz-ng/src/hb-set-private.hh +++ b/third_party/harfbuzz-ng/src/hb-set-private.hh @@ -32,47 +32,31 @@ #include "hb-object-private.hh" -struct hb_set_digest_common_bits_t -{ - ASSERT_POD (); - - typedef unsigned int mask_t; - - inline void init (void) { - mask = ~0; - value = (mask_t) -1; - } - - inline void add (hb_codepoint_t g) { - if (unlikely (value == (mask_t) -1)) { - value = g; - return; - } - - mask ^= (g & mask) ^ value; - value &= mask; - } - - inline void add_range (hb_codepoint_t a, hb_codepoint_t b) { - /* The negation here stands for ~(x-1). */ - mask &= -(1 << _hb_bit_storage (a ^ b)); - value &= mask; - } - - inline bool may_have (hb_codepoint_t g) const { - return (g & mask) == value; - } - - private: - mask_t mask; - mask_t value; -}; +/* + * The set digests here implement various "filters" that support + * "approximate member query". Conceptually these are like Bloom + * Filter and Quotient Filter, however, much smaller, faster, and + * designed to fit the requirements of our uses for glyph coverage + * queries. As a result, our filters have much higher. + */ +template <typename mask_t, unsigned int shift> struct hb_set_digest_lowest_bits_t { ASSERT_POD (); - typedef unsigned long mask_t; + static const unsigned int mask_bytes = sizeof (mask_t); + static const unsigned int mask_bits = sizeof (mask_t) * 8; + static const unsigned int num_bits = 0 + + (mask_bytes >= 1 ? 3 : 0) + + (mask_bytes >= 2 ? 1 : 0) + + (mask_bytes >= 4 ? 1 : 0) + + (mask_bytes >= 8 ? 1 : 0) + + (mask_bytes >= 16? 1 : 0) + + 0; + + ASSERT_STATIC (shift < sizeof (hb_codepoint_t) * 8); + ASSERT_STATIC (shift + num_bits <= sizeof (hb_codepoint_t) * 8); inline void init (void) { mask = 0; @@ -83,7 +67,7 @@ struct hb_set_digest_lowest_bits_t } inline void add_range (hb_codepoint_t a, hb_codepoint_t b) { - if (b - a >= sizeof (mask_t) * 8 - 1) + if ((b >> shift) - (a >> shift) >= mask_bits - 1) mask = (mask_t) -1; else { mask_t ma = mask_for (a); @@ -98,39 +82,66 @@ struct hb_set_digest_lowest_bits_t private: - static inline mask_t mask_for (hb_codepoint_t g) { return ((mask_t) 1) << (g & (sizeof (mask_t) * 8 - 1)); } + static inline mask_t mask_for (hb_codepoint_t g) { + return ((mask_t) 1) << ((g >> shift) & (mask_bits - 1)); + } mask_t mask; }; -struct hb_set_digest_t +template <typename head_t, typename tail_t> +struct hb_set_digest_combiner_t { ASSERT_POD (); inline void init (void) { - digest1.init (); - digest2.init (); + head.init (); + tail.init (); } inline void add (hb_codepoint_t g) { - digest1.add (g); - digest2.add (g); + head.add (g); + tail.add (g); } inline void add_range (hb_codepoint_t a, hb_codepoint_t b) { - digest1.add_range (a, b); - digest2.add_range (a, b); + head.add_range (a, b); + tail.add_range (a, b); } inline bool may_have (hb_codepoint_t g) const { - return digest1.may_have (g) && digest2.may_have (g); + return head.may_have (g) && tail.may_have (g); } private: - hb_set_digest_common_bits_t digest1; - hb_set_digest_lowest_bits_t digest2; + head_t head; + tail_t tail; }; +/* + * hb_set_digest_t + * + * This is a combination of digests that performs "best". + * There is not much science to this: it's a result of intuition + * and testing. + */ +typedef hb_set_digest_combiner_t +< + hb_set_digest_lowest_bits_t<unsigned long, 4>, + hb_set_digest_combiner_t + < + hb_set_digest_lowest_bits_t<unsigned long, 0>, + hb_set_digest_lowest_bits_t<unsigned long, 9> + > +> hb_set_digest_t; + + + +/* + * hb_set_t + */ + + /* TODO Make this faster and memmory efficient. */ struct hb_set_t @@ -286,7 +297,7 @@ struct hb_set_t { for (unsigned int i = 0; i < ELTS; i++) if (elts[i]) - for (unsigned int j = 0; i < BITS; j++) + for (unsigned int j = 0; j < BITS; j++) if (elts[i] & (1 << j)) return i * BITS + j; return SENTINEL; diff --git a/third_party/harfbuzz-ng/src/hb-set.cc b/third_party/harfbuzz-ng/src/hb-set.cc index 5f427a5..3c9573f 100644 --- a/third_party/harfbuzz-ng/src/hb-set.cc +++ b/third_party/harfbuzz-ng/src/hb-set.cc @@ -27,7 +27,6 @@ #include "hb-set-private.hh" - /* Public API */ diff --git a/third_party/harfbuzz-ng/src/hb-unicode-private.hh b/third_party/harfbuzz-ng/src/hb-unicode-private.hh index 155a8a3..dd4d001 100644 --- a/third_party/harfbuzz-ng/src/hb-unicode-private.hh +++ b/third_party/harfbuzz-ng/src/hb-unicode-private.hh @@ -128,6 +128,9 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE * is NOT Default_Ignorable, but it really behaves in a way that it should * be. That has been reported to the Unicode Technical Committee for * consideration. As such, we include it here, since Uniscribe removes it. + * It *is* in Unicode 6.3 however. U+061C ARABIC LETTER MARK from Unicode + * 6.3 is also added manually. The new Unicode 6.3 bidi formatting + * characters are encoded in a block that was Default_Ignorable already. * * Note: While U+115F and U+1160 are Default_Ignorable, we do NOT want to * hide them, as the way Uniscribe has implemented them is with regular @@ -173,6 +176,7 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE switch (page) { case 0x00: return unlikely (ch == 0x00AD); case 0x03: return unlikely (ch == 0x034F); + case 0x06: return unlikely (ch == 0x061C); case 0x17: return hb_in_range<hb_codepoint_t> (ch, 0x17B4, 0x17B5); case 0x18: return hb_in_range<hb_codepoint_t> (ch, 0x180B, 0x180E); case 0x20: return hb_in_ranges<hb_codepoint_t> (ch, 0x200B, 0x200F, diff --git a/third_party/harfbuzz-ng/src/hb-version.h b/third_party/harfbuzz-ng/src/hb-version.h index dadcde2..29b1c06 100644 --- a/third_party/harfbuzz-ng/src/hb-version.h +++ b/third_party/harfbuzz-ng/src/hb-version.h @@ -38,9 +38,9 @@ HB_BEGIN_DECLS #define HB_VERSION_MAJOR 0 #define HB_VERSION_MINOR 9 -#define HB_VERSION_MICRO 14 +#define HB_VERSION_MICRO 17 -#define HB_VERSION_STRING "0.9.14" +#define HB_VERSION_STRING "0.9.17" #define HB_VERSION_CHECK(major,minor,micro) \ ((major)*10000+(minor)*100+(micro) >= \ diff --git a/third_party/harfbuzz-ng/src/test.cc b/third_party/harfbuzz-ng/src/test.cc index 22108b8..1acb6ea 100644 --- a/third_party/harfbuzz-ng/src/test.cc +++ b/third_party/harfbuzz-ng/src/test.cc @@ -100,6 +100,7 @@ main (int argc, char **argv) hb_buffer_t *buffer = hb_buffer_create (); hb_buffer_add_utf8 (buffer, "\xe0\xa4\x95\xe0\xa5\x8d\xe0\xa4\xb0\xe0\xa5\x8d\xe0\xa4\x95", -1, 0, -1); + hb_buffer_guess_segment_properties (buffer); hb_shape (font, buffer, NULL, 0); |