summaryrefslogtreecommitdiffstats
path: root/src/3rdparty
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-12-15 13:00:39 +0100
committerLars Knoll <lars.knoll@qt.io>2017-12-30 15:17:28 +0000
commit809200a83e366141d543336503635cf57c626434 (patch)
treefc3aa70aa67f69ea2247a7ef30819ff4e98ead1b /src/3rdparty
parent89b0364cded81457eaa264c1634af5d082da3c21 (diff)
Update bundled HarfBuzz-NG copy to 1.7.4
This is the latest released version, fixing a large amount of bugs and adding Unicode 10 support. [ChangeLog] Bundled HarfBuzz-NG copy updated to 1.7.4 Change-Id: Idc8092dfc4e593d64fff2fd51ff9e1b3d84049a7 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/3rdparty')
-rw-r--r--src/3rdparty/harfbuzz-ng/NEWS276
-rw-r--r--src/3rdparty/harfbuzz-ng/README9
-rw-r--r--src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro19
-rw-r--r--src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-ot-var.h1
-rw-r--r--src/3rdparty/harfbuzz-ng/patches/0001-Qt-specific-workaround-for-AAT-shaper.patch58
-rw-r--r--src/3rdparty/harfbuzz-ng/qt_attribution.json2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh12
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-blob.cc27
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh144
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc42
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer.cc230
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer.h67
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-common.cc470
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-common.h60
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-coretext.cc337
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-coretext.h4
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-debug.hh431
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-deprecated.h4
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-dsalgs.hh167
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-face-private.hh12
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-face.cc53
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-face.h5
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc8
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-font-private.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-font.cc210
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-font.h29
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-mutex-private.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-object-private.hh10
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh56
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh277
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-cbdt-table.hh183
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh247
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc534
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh120
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh28
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh23
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh123
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-kern-table.hh394
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh261
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh32
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh142
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh102
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh478
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh4
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh44
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc91
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-map-private.hh38
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc25
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-math-table.hh722
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-math.cc33
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh24
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-os2-table.hh70
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-post-macroman.hh294
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh187
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh18
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh29
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-win1256.hh32
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc134
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-default.cc22
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc36
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hebrew.cc20
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh1616
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh11
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-table.cc92
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc129
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.hh378
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc52
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh58
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc35
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-tibetan.cc20
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-machine.hh437
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-private.hh3
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-table.cc147
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use.cc44
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc9
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc74
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh6
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc151
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc110
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-var-avar-table.hh149
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-var-fvar-table.hh209
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-var-hvar-table.hh165
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-var-mvar-table.hh114
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-var.cc159
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-var.h105
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot.h1
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-private.hh587
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-set-digest-private.hh179
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-set-private.hh647
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-set.cc9
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-set.h3
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc65
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shape.cc258
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shape.h16
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shaper-private.hh32
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shaper.cc6
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-string-array.hh81
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh33
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-unicode.cc4
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-utf-private.hh18
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-version.h6
102 files changed, 9479 insertions, 4255 deletions
diff --git a/src/3rdparty/harfbuzz-ng/NEWS b/src/3rdparty/harfbuzz-ng/NEWS
index 8c3ef117dd..7434bcada0 100644
--- a/src/3rdparty/harfbuzz-ng/NEWS
+++ b/src/3rdparty/harfbuzz-ng/NEWS
@@ -1,3 +1,261 @@
+Overview of changes leading to 1.7.4
+Wednesday, December 20, 2017
+====================================
+
+- Fix collect_glyphs() regression caused by hb_set_t changes.
+
+
+Overview of changes leading to 1.7.3
+Monday, December 18, 2017
+====================================
+
+- hb_set_t performance tuning and optimizations.
+- Speed up collect_glyphs() and reject garbage data.
+- In hb_coretext_font_create() set font point-size (ptem).
+- Misc fixes.
+
+
+Overview of changes leading to 1.7.2
+Monday, December 4, 2017
+====================================
+
+- Optimize hb_set_add_range().
+- Misc fixes.
+- New API:
+hb_coretext_font_create()
+
+
+Overview of changes leading to 1.7.1
+Tuesday, November 14, 2017
+====================================
+
+- Fix atexit object destruction regression.
+- Fix minor integer-overflow.
+
+
+Overview of changes leading to 1.7.0
+Monday, November 13, 2017
+====================================
+
+- Minor Indic fixes.
+- Implement kerning and glyph names in hb-ot-font.
+- Various DSO optimization re .data and .bss sizes.
+- Make C++11 optional; build fixes.
+- Mark all other backends "unsafe-to-break".
+- Graphite fix.
+
+
+Overview of changes leading to 1.6.3
+Thursday, October 26th, 2017
+====================================
+
+- Fix hb_set_t some more. Should be solid now.
+- Implement get_glyph_name() for hb-ot-font.
+- Misc fixes.
+
+
+Overview of changes leading to 1.6.2
+Monday, October 23nd, 2017
+====================================
+
+- Yesterday's release had a bad crasher; don't use it. That's what
+ happens when one works on Sunday...
+ https://github.com/harfbuzz/harfbuzz/issues/578
+- Build fixes for FreeBSD and Chrome Android.
+
+
+Overview of changes leading to 1.6.1
+Sunday, October 22nd, 2017
+====================================
+
+- Don't skip over COMBINING GRAPHEME JOINER when ligating, etc.
+ To be refined: https://github.com/harfbuzz/harfbuzz/issues/554
+- Faster hb_set_t implementation.
+- Don't use deprecated ICU API.
+- Fix undefined-behavior in Myanmar shaper, introduced in 1.6.0
+- Deprecated API:
+ hb_set_invert()
+
+
+Overview of changes leading to 1.6.0
+Friday, October the 13th, 2017
+====================================
+
+- Update to Unicode 10.
+
+- Various Indic and Universal Shaping Engine fixes as a result of
+ HarfBuzz Hackfest with Jonathan Kew at Web Engines Hackfest at
+ the Igalia offices in A Coruña, Spain. Thanks Igalia for having
+ us!
+
+- Implement Unicode Arabic Mark Ordering Algorithm UTR#53.
+
+- Implement optical sizing / tracking in CoreText backend, using
+ new API hb_font_set_ptem().
+
+- Allow notifying hb_font_t that underlying FT_Face changed sizing,
+ using new API hb_ft_font_changed().
+
+- More Graphite backend RTL fixes.
+
+- Fix caching of variable font shaping plans.
+
+- hb-view / hb-shape now accept following new arguments:
+
+ o --unicodes: takes a list of hex numbers that represent Unicode
+ codepoints.
+
+New API:
++hb_face_get_table_tags()
++hb_font_set_ptem()
++hb_font_get_ptem()
++hb_ft_font_changed()
+
+
+Overview of changes leading to 1.5.1
+Tuesday, September 5, 2017
+====================================
+
+- Fix "unsafe-to-break" in fallback shaping and other corner cases.
+ All our tests pass with --verify now, meaning unsafe-to-break API
+ works as expected.
+- Add --unicodes to hb-view / hb-shape.
+- [indic] Treat Consonant_With_Stacker as consonant. This will need
+ further tweaking.
+- hb_buffer_diff() tweaks.
+
+
+Overview of changes leading to 1.5.0
+Wednesday, August 23, 2017
+====================================
+
+- Misc new API, for appending a buffer to another, and for comparing
+ contents of two buffers for types of differences.
+
+- New "unsafe-to-break" API. Can be used to speed up reshaping
+ in line-breaking situations. Essentially, after shaping, it returns
+ positions in the input string (some of the cluster boundaries) that
+ are "safe to break" in that if the text is segmented at that position
+ and two sides reshaped and concatenated, the shaping result is
+ exactly the same as shaping the text in one piece.
+
+ hb-view and hb-shape and hb-shape now take --verify, which verifies
+ the above property.
+
+ Some corner cases of the implementation are still not quite working.
+ Those will be fixed in subsequent releases.
+
+- New API:
+
+hb_buffer_append()
+
+hb_glyph_flags_t
+HB_GLYPH_FLAG_UNSAFE_TO_BREAK
+HB_GLYPH_FLAG_DEFINED
+hb_glyph_info_get_glyph_flags()
+
+HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS
+
+hb_buffer_diff_flags_t
+HB_BUFFER_DIFF_FLAG_EQUAL
+HB_BUFFER_DIFF_FLAG_CONTENT_TYPE_MISMATCH
+HB_BUFFER_DIFF_FLAG_LENGTH_MISMATCH
+HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT
+HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT
+HB_BUFFER_DIFF_FLAG_CODEPOINT_MISMATCH
+HB_BUFFER_DIFF_FLAG_CLUSTER_MISMATCH
+HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH
+HB_BUFFER_DIFF_FLAG_POSITION_MISMATCH
+hb_buffer_diff
+
+
+Overview of changes leading to 1.4.8
+Tuesday, August 8, 2017
+====================================
+
+- Major fix to avar table handling.
+- Rename hb-shape --show-message to --trace.
+- Build fixes.
+
+
+Overview of changes leading to 1.4.7
+Tuesday, July 18, 2017
+====================================
+
+- Multiple Indic, Tibetan, and Cham fixes.
+- CoreText: Allow disabling kerning.
+- Adjust Arabic feature order again.
+- Misc build fixes.
+
+
+Overview of changes leading to 1.4.6
+Sunday, April 23, 2017
+====================================
+
+- Graphite2: Fix RTL positioning issue.
+- Backlist GDEF of more versions of Padauk and Tahoma.
+- New, experimental, cmake alternative build system.
+
+
+Overview of changes leading to 1.4.5
+Friday, March 10, 2017
+====================================
+
+- Revert "Fix Context lookup application when moving back after a glyph..."
+ This introduced memory access problems. To be fixed properly soon.
+
+
+Overview of changes leading to 1.4.4
+Sunday, March 5, 2017
+====================================
+
+- Fix Context lookup application when moving back after a glyph deletion.
+- Fix buffer-overrun in Bengali.
+
+
+Overview of changes leading to 1.4.3
+Saturday, February 25, 2017
+====================================
+
+- Route Adlam script to Arabic shaper.
+- Misc fixes.
+- New API:
+ hb_font_set_face()
+- Deprecate API:
+ hb_graphite2_font_get_gr_font()
+
+
+Overview of changes leading to 1.4.2
+Monday, January 23, 2017
+====================================
+
+- Implement OpenType Font Variation tables avar/fvar/HVAR/VVAR.
+- hb-shape and hb-view now accept --variations.
+- New API:
+
+hb_variation_t
+hb_variation_from_string()
+hb_variation_to_string()
+
+hb_font_set_variations()
+hb_font_set_var_coords_design()
+hb_font_get_var_coords_normalized()
+
+hb-ot-var.h:
+hb_ot_var_axis_t
+hb_ot_var_has_data()
+hb_ot_var_get_axis_count()
+hb_ot_var_get_axes()
+hb_ot_var_find_axis()
+hb_ot_var_normalize_variations()
+hb_ot_var_normalize_coords()
+
+- MVAR to be implemented later. Access to named instances to be
+ implemented later as well.
+
+- Misc fixes.
+
+
Overview of changes leading to 1.4.1
Thursday, January 5, 2017
====================================
@@ -212,7 +470,7 @@ Tuesday, February 23, 2016
- CoreText: Drastically speed up font initialization.
- CoreText: Fix tiny leak.
- Group ZWJ/ZWNJ with previous syllable under cluster-level=0.
- https://github.com/behdad/harfbuzz/issues/217
+ https://github.com/harfbuzz/harfbuzz/issues/217
- Add test/shaping/README.md about how to add tests to the suite.
@@ -228,8 +486,8 @@ Friday, February 19, 2016
- Allow GPOS cursive connection on marks, and fix the interaction with
mark attachment. This work resulted in some changes to how mark
attachments work. See:
- https://github.com/behdad/harfbuzz/issues/211
- https://github.com/behdad/harfbuzz/commit/86c68c7a2c971efe8e35b1f1bd99401dc8b688d2
+ https://github.com/harfbuzz/harfbuzz/issues/211
+ https://github.com/harfbuzz/harfbuzz/commit/86c68c7a2c971efe8e35b1f1bd99401dc8b688d2
- Graphite2 shaper: improved negative advance handling (eg. Nastaliq).
- Add nmake-based build system for Windows.
- Minor speedup.
@@ -270,7 +528,7 @@ Wednesday, November 26, 2015
====================================
- Fix badly-broken fallback shaper that affected terminology.
- https://github.com/behdad/harfbuzz/issues/187
+ https://github.com/harfbuzz/harfbuzz/issues/187
- Fix y_scaling in Graphite shaper.
- API changes:
* An unset glyph_h_origin() function in font-funcs now (sensibly)
@@ -292,11 +550,11 @@ Wednesday, November 18, 2015
====================================
- Implement 'stch' stretch feature for Syriac Abbreviation Mark.
- https://github.com/behdad/harfbuzz/issues/141
+ https://github.com/harfbuzz/harfbuzz/issues/141
- Disable use of decompose_compatibility() callback.
- Implement "shaping" of various Unicode space characters, even
if the font does not support them.
- https://github.com/behdad/harfbuzz/issues/153
+ https://github.com/harfbuzz/harfbuzz/issues/153
- If font does not support U+2011 NO-BREAK HYPHEN, fallback to
U+2010 HYPHEN.
- Changes resulting from libFuzzer continuous fuzzing:
@@ -319,7 +577,7 @@ Thursday, October 15, 2015
- Revert default load-flags of fonts created using hb_ft_font_create()
back to FT_LOAD_DEFAULT|FT_LOAD_NO_HINTING. This was changed in
last release (1.0.5), but caused major issues, so revert.
- https://github.com/behdad/harfbuzz/issues/143
+ https://github.com/harfbuzz/harfbuzz/issues/143
Overview of changes leading to 1.0.5
@@ -327,7 +585,7 @@ Tuesday, October 13, 2015
====================================
- Fix multiple memory access bugs discovered using libFuzzer.
- https://github.com/behdad/harfbuzz/issues/139
+ https://github.com/harfbuzz/harfbuzz/issues/139
Everyone should upgrade to this version as soon as possible.
We now have continuous fuzzing set up, to avoid issues like
these creeping in again.
@@ -598,7 +856,7 @@ Wednesday, July 16, 2014
U+FFFD REPLACEMENT CHARACTER now.
- With all changes in this release, the buffer will contain fully
valid Unicode after hb_buffer_add_utf8/16/32 no matter how
- broken the input is. This can be overriden though. See below.
+ broken the input is. This can be overridden though. See below.
- Fix Mongolian Variation Selectors for fonts without GDEF.
- Fix minor invalid buffer access.
- Accept zh-Hant and zh-Hans language tags. hb_ot_tag_to_language()
diff --git a/src/3rdparty/harfbuzz-ng/README b/src/3rdparty/harfbuzz-ng/README
index 69a1bdd9ff..aa055169d5 100644
--- a/src/3rdparty/harfbuzz-ng/README
+++ b/src/3rdparty/harfbuzz-ng/README
@@ -1,6 +1,7 @@
-[![Build Status](https://travis-ci.org/behdad/harfbuzz.svg)](https://travis-ci.org/behdad/harfbuzz)
-[![Build Status](https://ci.appveyor.com/api/projects/status/4oaq58ns2h0m2soa?svg=true)](https://ci.appveyor.com/project/behdad/harfbuzz)
-[![Coverage Status](https://img.shields.io/coveralls/behdad/harfbuzz.svg)](https://coveralls.io/r/behdad/harfbuzz)
+[![Build Status](https://travis-ci.org/harfbuzz/harfbuzz.svg)](https://travis-ci.org/harfbuzz/harfbuzz)
+[![Build status](https://ci.appveyor.com/api/projects/status/0t0flrxpstj9lb9w?svg=true)](https://ci.appveyor.com/project/harfbuzz/harfbuzz)
+[![CircleCI](https://circleci.com/gh/harfbuzz/harfbuzz.svg?style=svg)](https://circleci.com/gh/harfbuzz/harfbuzz)
+[![Coverage Status](https://img.shields.io/coveralls/harfbuzz/harfbuzz.svg)](https://coveralls.io/r/harfbuzz/harfbuzz)
[ABI Tracker](http://abi-laboratory.pro/tracker/timeline/harfbuzz/)
This is HarfBuzz, a text shaping library.
@@ -10,3 +11,5 @@ For bug reports, mailing list, and other information please visit:
http://harfbuzz.org/
For license information, see the file COPYING.
+
+Documentation: https://harfbuzz.github.io
diff --git a/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro b/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro
index e5746bf3eb..ad40b98753 100644
--- a/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro
+++ b/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro
@@ -56,6 +56,8 @@ HEADERS += \
$$PWD/src/hb-buffer-deserialize-json.hh \
$$PWD/src/hb-buffer-deserialize-text.hh \
$$PWD/src/hb-cache-private.hh \
+ $$PWD/src/hb-debug.hh \
+ $$PWD/src/hb-dsalgs.hh \
$$PWD/src/hb-face-private.hh \
$$PWD/src/hb-font-private.hh \
$$PWD/src/hb-mutex-private.hh \
@@ -73,11 +75,13 @@ HEADERS += \
$$PWD/src/hb-ot-os2-table.hh \
$$PWD/src/hb-ot-post-table.hh \
$$PWD/src/hb-private.hh \
+ $$PWD/src/hb-set-digest-private.hh \
$$PWD/src/hb-set-private.hh \
$$PWD/src/hb-shape-plan-private.hh \
$$PWD/src/hb-shaper-impl-private.hh \
$$PWD/src/hb-shaper-list.hh \
$$PWD/src/hb-shaper-private.hh \
+ $$PWD/src/hb-string-array.hh \
$$PWD/src/hb-unicode-private.hh \
$$PWD/src/hb-utf-private.hh
@@ -116,9 +120,11 @@ contains(SHAPERS, opentype) {
$$PWD/src/hb-ot-shape-complex-use.cc \
$$PWD/src/hb-ot-shape-complex-use-table.cc \
$$PWD/src/hb-ot-shape-fallback.cc \
- $$PWD/src/hb-ot-shape-normalize.cc
+ $$PWD/src/hb-ot-shape-normalize.cc \
+ $$PWD/src/hb-ot-var.cc
HEADERS += \
+ $$PWD/src/hb-ot-kern-table.hh \
$$PWD/src/hb-ot-layout-common-private.hh \
$$PWD/src/hb-ot-layout-gdef-table.hh \
$$PWD/src/hb-ot-layout-gpos-table.hh \
@@ -128,6 +134,8 @@ contains(SHAPERS, opentype) {
$$PWD/src/hb-ot-layout-math-table.hh \
$$PWD/src/hb-ot-layout-private.hh \
$$PWD/src/hb-ot-map-private.hh \
+ $$PWD/src/hb-ot-math-table.hh \
+ $$PWD/src/hb-ot-post-macroman.hh \
$$PWD/src/hb-ot-shape-complex-arabic-fallback.hh \
$$PWD/src/hb-ot-shape-complex-arabic-private.hh \
$$PWD/src/hb-ot-shape-complex-arabic-table.hh \
@@ -140,7 +148,11 @@ contains(SHAPERS, opentype) {
$$PWD/src/hb-ot-shape-complex-use-private.hh \
$$PWD/src/hb-ot-shape-fallback-private.hh \
$$PWD/src/hb-ot-shape-normalize-private.hh \
- $$PWD/src/hb-ot-shape-private.hh
+ $$PWD/src/hb-ot-shape-private.hh \
+ $$PWD/src/hb-ot-var-avar-table.hh \
+ $$PWD/src/hb-ot-var-fvar-table.hh \
+ $$PWD/src/hb-ot-var-hvar-table.hh \
+ $$PWD/src/hb-ot-var-mvar-table.hh
HEADERS += \
$$PWD/src/hb-ot.h \
@@ -148,7 +160,8 @@ contains(SHAPERS, opentype) {
$$PWD/src/hb-ot-layout.h \
$$PWD/src/hb-ot-math.h \
$$PWD/src/hb-ot-shape.h \
- $$PWD/src/hb-ot-tag.h
+ $$PWD/src/hb-ot-tag.h \
+ $$PWD/src/hb-ot-var.h
}
contains(SHAPERS, coretext) {
diff --git a/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-ot-var.h b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-ot-var.h
new file mode 100644
index 0000000000..629acbcb64
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-ot-var.h
@@ -0,0 +1 @@
+#include "../../src/hb-ot-var.h"
diff --git a/src/3rdparty/harfbuzz-ng/patches/0001-Qt-specific-workaround-for-AAT-shaper.patch b/src/3rdparty/harfbuzz-ng/patches/0001-Qt-specific-workaround-for-AAT-shaper.patch
new file mode 100644
index 0000000000..470e0ffe5a
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/patches/0001-Qt-specific-workaround-for-AAT-shaper.patch
@@ -0,0 +1,58 @@
+From: Konstantin Ritt <ritt.ks@gmail.com>
+Date: Sun, 17 Dec 2017 07:46:20 +0400
+Subject: Qt-specific workaround for AAT shaper
+
+CoreText API doesn't give us a fontdata to reconstruct the original font,
+so we have to store the CTFont and CGFont of interest in context object
+passed to HB from native font engine
+---
+ src/3rdparty/harfbuzz-ng/src/hb-coretext.cc | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc
+index 2dd10d2..c993ec0 100644
+--- a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc
++++ b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc
+@@ -35,6 +35,20 @@
+ #include "hb-coretext.h"
+ #include <math.h>
+
++
++typedef bool (*qt_get_font_table_func_t) (void *user_data, unsigned int tag, unsigned char *buffer, unsigned int *length);
++
++struct FontEngineFaceData {
++ void *user_data;
++ qt_get_font_table_func_t get_font_table;
++};
++
++struct CoreTextFontEngineData {
++ CTFontRef ctFont;
++ CGFontRef cgFont;
++};
++
++
+ /* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */
+ #define HB_CORETEXT_DEFAULT_FONT_SIZE 12.f
+
+@@ -129,6 +143,7 @@ create_cg_font (hb_face_t *face)
+ }
+ else
+ {
++#if 0
+ hb_blob_t *blob = hb_face_reference_blob (face);
+ unsigned int blob_length;
+ const char *blob_data = hb_blob_get_data (blob, &blob_length);
+@@ -143,6 +158,11 @@ create_cg_font (hb_face_t *face)
+ DEBUG_MSG (CORETEXT, face, "Face CGFontCreateWithDataProvider() failed");
+ CGDataProviderRelease (provider);
+ }
++#else
++ FontEngineFaceData *fontEngineFaceData = (FontEngineFaceData *) face->user_data;
++ CoreTextFontEngineData *coreTextFontEngineData = (CoreTextFontEngineData *) fontEngineFaceData->user_data;
++ cg_font = CGFontRetain (coreTextFontEngineData->cgFont);
++#endif
+ }
+ return cg_font;
+ }
+--
+
diff --git a/src/3rdparty/harfbuzz-ng/qt_attribution.json b/src/3rdparty/harfbuzz-ng/qt_attribution.json
index a5eee600d6..0cf6a746f5 100644
--- a/src/3rdparty/harfbuzz-ng/qt_attribution.json
+++ b/src/3rdparty/harfbuzz-ng/qt_attribution.json
@@ -6,7 +6,7 @@
"Description": "HarfBuzz is an OpenType text shaping engine.",
"Homepage": "http://harfbuzz.org",
- "Version": "1.4.1",
+ "Version": "1.7.4",
"License": "MIT License",
"LicenseId": "MIT",
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh
index 100ba539e3..9343840140 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh
@@ -89,9 +89,9 @@ typedef int32_t hb_atomic_int_impl_t;
#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P))
#else
#if __ppc64__ || __x86_64__ || __aarch64__
-#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap64Barrier ((int64_t) (O), (int64_t) (N), (int64_t*) (P))
+#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap64Barrier ((int64_t) (void *) (O), (int64_t) (void *) (N), (int64_t*) (P))
#else
-#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (O), (int32_t) (N), (int32_t*) (P))
+#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (void *) (O), (int32_t) (void *) (N), (int32_t*) (P))
#endif
#endif
@@ -124,13 +124,13 @@ typedef unsigned int hb_atomic_int_impl_t;
#include <builtins.h>
-static inline int hb_fetch_and_add(volatile int* AI, unsigned int V) {
+static inline int _hb_fetch_and_add(volatile int* AI, unsigned int V) {
__lwsync();
int result = __fetch_and_add(AI, V);
__isync();
return result;
}
-static inline int hb_compare_and_swaplp(volatile long* P, long O, long N) {
+static inline int _hb_compare_and_swaplp(volatile long* P, long O, long N) {
__sync();
int result = __compare_and_swaplp (P, &O, N);
__sync();
@@ -139,10 +139,10 @@ static inline int hb_compare_and_swaplp(volatile long* P, long O, long N) {
typedef int hb_atomic_int_impl_t;
#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
-#define hb_atomic_int_impl_add(AI, V) hb_fetch_and_add (&(AI), (V))
+#define hb_atomic_int_impl_add(AI, V) _hb_fetch_and_add (&(AI), (V))
#define hb_atomic_ptr_impl_get(P) (__sync(), (void *) *(P))
-#define hb_atomic_ptr_impl_cmpexch(P,O,N) hb_compare_and_swaplp ((long*)(P), (long)(O), (long)(N))
+#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_compare_and_swaplp ((long*)(P), (long)(O), (long)(N))
#elif !defined(HB_NO_MT)
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-blob.cc b/src/3rdparty/harfbuzz-ng/src/hb-blob.cc
index fb48f03cab..59c8333637 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-blob.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-blob.cc
@@ -30,6 +30,7 @@
#endif
#include "hb-private.hh"
+#include "hb-debug.hh"
#include "hb-object-private.hh"
@@ -44,12 +45,6 @@
#include <errno.h>
-
-#ifndef HB_DEBUG_BLOB
-#define HB_DEBUG_BLOB (HB_DEBUG+0)
-#endif
-
-
struct hb_blob_t {
hb_object_header_t header;
ASSERT_POD ();
@@ -72,8 +67,8 @@ _hb_blob_destroy_user_data (hb_blob_t *blob)
{
if (blob->destroy) {
blob->destroy (blob->user_data);
- blob->user_data = NULL;
- blob->destroy = NULL;
+ blob->user_data = nullptr;
+ blob->destroy = nullptr;
}
}
@@ -128,6 +123,12 @@ hb_blob_create (const char *data,
return blob;
}
+static void
+_hb_blob_destroy (void *data)
+{
+ hb_blob_destroy ((hb_blob_t *) data);
+}
+
/**
* hb_blob_create_sub_blob:
* @parent: Parent blob.
@@ -164,7 +165,7 @@ hb_blob_create_sub_blob (hb_blob_t *parent,
MIN (length, parent->length - offset),
HB_MEMORY_MODE_READONLY,
hb_blob_reference (parent),
- (hb_destroy_func_t) hb_blob_destroy);
+ _hb_blob_destroy);
return blob;
}
@@ -188,12 +189,12 @@ hb_blob_get_empty (void)
true, /* immutable */
- NULL, /* data */
+ nullptr, /* data */
0, /* length */
HB_MEMORY_MODE_READONLY, /* mode */
- NULL, /* user_data */
- NULL /* destroy */
+ nullptr, /* user_data */
+ nullptr /* destroy */
};
return const_cast<hb_blob_t *> (&_hb_blob_nil);
@@ -373,7 +374,7 @@ hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length)
if (length)
*length = 0;
- return NULL;
+ return nullptr;
}
if (length)
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh
index bca308da2f..97bdc1be30 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh
@@ -35,8 +35,8 @@
#include "hb-unicode-private.hh"
-#ifndef HB_BUFFER_MAX_EXPANSION_FACTOR
-#define HB_BUFFER_MAX_EXPANSION_FACTOR 32
+#ifndef HB_BUFFER_MAX_LEN_FACTOR
+#define HB_BUFFER_MAX_LEN_FACTOR 32
#endif
#ifndef HB_BUFFER_MAX_LEN_MIN
#define HB_BUFFER_MAX_LEN_MIN 8192
@@ -45,11 +45,22 @@
#define HB_BUFFER_MAX_LEN_DEFAULT 0x3FFFFFFF /* Shaping more than a billion chars? Let us know! */
#endif
-ASSERT_STATIC (sizeof (hb_glyph_info_t) == 20);
-ASSERT_STATIC (sizeof (hb_glyph_info_t) == sizeof (hb_glyph_position_t));
+#ifndef HB_BUFFER_MAX_OPS_FACTOR
+#define HB_BUFFER_MAX_OPS_FACTOR 64
+#endif
+#ifndef HB_BUFFER_MAX_OPS_MIN
+#define HB_BUFFER_MAX_OPS_MIN 1024
+#endif
+#ifndef HB_BUFFER_MAX_OPS_DEFAULT
+#define HB_BUFFER_MAX_OPS_DEFAULT 0x1FFFFFFF /* Shaping more than a billion operations? Let us know! */
+#endif
+
+static_assert ((sizeof (hb_glyph_info_t) == 20), "");
+static_assert ((sizeof (hb_glyph_info_t) == sizeof (hb_glyph_position_t)), "");
HB_MARK_AS_FLAG_T (hb_buffer_flags_t);
HB_MARK_AS_FLAG_T (hb_buffer_serialize_flags_t);
+HB_MARK_AS_FLAG_T (hb_buffer_diff_flags_t);
enum hb_buffer_scratch_flags_t {
HB_BUFFER_SCRATCH_FLAG_DEFAULT = 0x00000000u,
@@ -57,6 +68,8 @@ enum hb_buffer_scratch_flags_t {
HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES = 0x00000002u,
HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK = 0x00000004u,
HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT = 0x00000008u,
+ HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK = 0x00000010u,
+
/* Reserved for complex shapers' internal use. */
HB_BUFFER_SCRATCH_FLAG_COMPLEX0 = 0x01000000u,
HB_BUFFER_SCRATCH_FLAG_COMPLEX1 = 0x02000000u,
@@ -81,6 +94,7 @@ struct hb_buffer_t {
hb_codepoint_t replacement; /* U+FFFD or something else. */
hb_buffer_scratch_flags_t scratch_flags; /* Have space-flallback, etc. */
unsigned int max_len; /* Maximum allowed len. */
+ int max_ops; /* Maximum allowed operations. */
/* Buffer contents */
hb_buffer_content_type_t content_type;
@@ -99,17 +113,6 @@ struct hb_buffer_t {
hb_glyph_info_t *out_info;
hb_glyph_position_t *pos;
- inline hb_glyph_info_t &cur (unsigned int i = 0) { return info[idx + i]; }
- inline hb_glyph_info_t cur (unsigned int i = 0) const { return info[idx + i]; }
-
- inline hb_glyph_position_t &cur_pos (unsigned int i = 0) { return pos[idx + i]; }
- inline hb_glyph_position_t cur_pos (unsigned int i = 0) const { return pos[idx + i]; }
-
- inline hb_glyph_info_t &prev (void) { return out_info[out_len ? out_len - 1 : 0]; }
- inline hb_glyph_info_t prev (void) const { return out_info[out_len ? out_len - 1 : 0]; }
-
- inline bool has_separate_output (void) const { return info != out_info; }
-
unsigned int serial;
/* Text before / after the main buffer contents.
@@ -129,6 +132,10 @@ struct hb_buffer_t {
#ifndef HB_NDEBUG
uint8_t allocated_var_bits;
#endif
+
+
+ /* Methods */
+
inline void allocate_var (unsigned int start, unsigned int count)
{
#ifndef HB_NDEBUG
@@ -165,8 +172,17 @@ struct hb_buffer_t {
#endif
}
+ inline hb_glyph_info_t &cur (unsigned int i = 0) { return info[idx + i]; }
+ inline hb_glyph_info_t cur (unsigned int i = 0) const { return info[idx + i]; }
+
+ inline hb_glyph_position_t &cur_pos (unsigned int i = 0) { return pos[idx + i]; }
+ inline hb_glyph_position_t cur_pos (unsigned int i = 0) const { return pos[idx + i]; }
+
+ inline hb_glyph_info_t &prev (void) { return out_info[out_len ? out_len - 1 : 0]; }
+ inline hb_glyph_info_t prev (void) const { return out_info[out_len ? out_len - 1 : 0]; }
+
+ inline bool has_separate_output (void) const { return info != out_info; }
- /* Methods */
HB_INTERNAL void reset (void);
HB_INTERNAL void clear (void);
@@ -232,25 +248,31 @@ struct hb_buffer_t {
for (unsigned int j = 0; j < len; j++)
info[j].mask |= mask;
}
- HB_INTERNAL void set_masks (hb_mask_t value,
- hb_mask_t mask,
- unsigned int cluster_start,
- unsigned int cluster_end);
+ HB_INTERNAL void set_masks (hb_mask_t value, hb_mask_t mask,
+ unsigned int cluster_start, unsigned int cluster_end);
- HB_INTERNAL void merge_clusters (unsigned int start,
- unsigned int end)
+ inline void merge_clusters (unsigned int start, unsigned int end)
{
if (end - start < 2)
return;
merge_clusters_impl (start, end);
}
- HB_INTERNAL void merge_clusters_impl (unsigned int start,
- unsigned int end);
- HB_INTERNAL void merge_out_clusters (unsigned int start,
- unsigned int end);
+ HB_INTERNAL void merge_clusters_impl (unsigned int start, unsigned int end);
+ HB_INTERNAL void merge_out_clusters (unsigned int start, unsigned int end);
/* Merge clusters for deleting current glyph, and skip it. */
HB_INTERNAL void delete_glyph (void);
+ inline void unsafe_to_break (unsigned int start,
+ unsigned int end)
+ {
+ if (end - start < 2)
+ return;
+ unsafe_to_break_impl (start, end);
+ }
+ HB_INTERNAL void unsafe_to_break_impl (unsigned int start, unsigned int end);
+ HB_INTERNAL void unsafe_to_break_from_outbuffer (unsigned int start, unsigned int end);
+
+
/* Internal methods */
HB_INTERNAL bool enlarge (unsigned int size);
@@ -282,9 +304,79 @@ struct hb_buffer_t {
return ret;
}
HB_INTERNAL bool message_impl (hb_font_t *font, const char *fmt, va_list ap) HB_PRINTF_FUNC(3, 0);
+
+ static inline void
+ set_cluster (hb_glyph_info_t &info, unsigned int cluster, unsigned int mask = 0)
+ {
+ if (info.cluster != cluster)
+ {
+ if (mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK)
+ info.mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
+ else
+ info.mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
+ }
+ info.cluster = cluster;
+ }
+
+ inline int
+ _unsafe_to_break_find_min_cluster (const hb_glyph_info_t *info,
+ unsigned int start, unsigned int end,
+ unsigned int cluster) const
+ {
+ for (unsigned int i = start; i < end; i++)
+ cluster = MIN<unsigned int> (cluster, info[i].cluster);
+ return cluster;
+ }
+ inline void
+ _unsafe_to_break_set_mask (hb_glyph_info_t *info,
+ unsigned int start, unsigned int end,
+ unsigned int cluster)
+ {
+ for (unsigned int i = start; i < end; i++)
+ if (cluster != info[i].cluster)
+ {
+ scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK;
+ info[i].mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
+ }
+ }
+
+ inline void
+ unsafe_to_break_all (void)
+ {
+ for (unsigned int i = 0; i < len; i++)
+ info[i].mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
+ }
+ inline void
+ safe_to_break_all (void)
+ {
+ for (unsigned int i = 0; i < len; i++)
+ info[i].mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
+ }
};
+/* Loop over clusters. Duplicated in foreach_syllable(). */
+#define foreach_cluster(buffer, start, end) \
+ for (unsigned int \
+ _count = buffer->len, \
+ start = 0, end = _count ? _next_cluster (buffer, 0) : 0; \
+ start < _count; \
+ start = end, end = _next_cluster (buffer, start))
+
+static inline unsigned int
+_next_cluster (hb_buffer_t *buffer, unsigned int start)
+{
+ hb_glyph_info_t *info = buffer->info;
+ unsigned int count = buffer->len;
+
+ unsigned int cluster = info[start].cluster;
+ while (++start < count && cluster == info[start].cluster)
+ ;
+
+ return start;
+}
+
+
#define HB_BUFFER_XALLOCATE_VAR(b, func, var) \
b->func (offsetof (hb_glyph_info_t, var) - offsetof(hb_glyph_info_t, var1), \
sizeof (b->info[0].var))
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc b/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc
index 63a0f34669..ea62e9ffdb 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc
@@ -30,7 +30,7 @@
static const char *serialize_formats[] = {
"text",
"json",
- NULL
+ nullptr
};
/**
@@ -90,7 +90,7 @@ hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format)
case HB_BUFFER_SERIALIZE_FORMAT_TEXT: return serialize_formats[0];
case HB_BUFFER_SERIALIZE_FORMAT_JSON: return serialize_formats[1];
default:
- case HB_BUFFER_SERIALIZE_FORMAT_INVALID: return NULL;
+ case HB_BUFFER_SERIALIZE_FORMAT_INVALID: return nullptr;
}
}
@@ -104,9 +104,9 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
hb_font_t *font,
hb_buffer_serialize_flags_t flags)
{
- hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, NULL);
+ hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr);
hb_glyph_position_t *pos = (flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS) ?
- NULL : hb_buffer_get_glyph_positions (buffer, NULL);
+ nullptr : hb_buffer_get_glyph_positions (buffer, nullptr);
*buf_consumed = 0;
for (unsigned int i = start; i < end; i++)
@@ -145,10 +145,16 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS))
{
- p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d",
- pos[i].x_offset, pos[i].y_offset);
- p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d",
- pos[i].x_advance, pos[i].y_advance);
+ p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d",
+ pos[i].x_offset, pos[i].y_offset));
+ p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d",
+ pos[i].x_advance, pos[i].y_advance));
+ }
+
+ if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS)
+ {
+ if (info[i].mask & HB_GLYPH_FLAG_DEFINED)
+ p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"fl\":%u", info[i].mask & HB_GLYPH_FLAG_DEFINED));
}
if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS)
@@ -156,9 +162,9 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
hb_glyph_extents_t extents;
hb_font_get_glyph_extents(font, info[i].codepoint, &extents);
p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"xb\":%d,\"yb\":%d",
- extents.x_bearing, extents.y_bearing));
+ extents.x_bearing, extents.y_bearing));
p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"w\":%d,\"h\":%d",
- extents.width, extents.height));
+ extents.width, extents.height));
}
*p++ = '}';
@@ -188,9 +194,9 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
hb_font_t *font,
hb_buffer_serialize_flags_t flags)
{
- hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, NULL);
+ hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr);
hb_glyph_position_t *pos = (flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS) ?
- NULL : hb_buffer_get_glyph_positions (buffer, NULL);
+ nullptr : hb_buffer_get_glyph_positions (buffer, nullptr);
*buf_consumed = 0;
for (unsigned int i = start; i < end; i++)
@@ -226,6 +232,12 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance));
}
+ if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS)
+ {
+ if (info[i].mask &HB_GLYPH_FLAG_DEFINED)
+ p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "#%X", info[i].mask &HB_GLYPH_FLAG_DEFINED));
+ }
+
if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS)
{
hb_glyph_extents_t extents;
@@ -311,6 +323,8 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
if (!buf_consumed)
buf_consumed = &sconsumed;
*buf_consumed = 0;
+ if (buf_size)
+ *buf = '\0';
assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID) ||
buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS);
@@ -408,8 +422,8 @@ hb_bool_t
hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
const char *buf,
int buf_len, /* -1 means nul-terminated */
- const char **end_ptr, /* May be NULL */
- hb_font_t *font, /* May be NULL */
+ const char **end_ptr, /* May be nullptr */
+ hb_font_t *font, /* May be nullptr */
hb_buffer_serialize_format_t format)
{
const char *end;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc b/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc
index 3940a3dbf8..7ead43b018 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc
@@ -31,10 +31,6 @@
#include "hb-utf-private.hh"
-#ifndef HB_DEBUG_BUFFER
-#define HB_DEBUG_BUFFER (HB_DEBUG+0)
-#endif
-
/**
* SECTION: hb-buffer
* @title: Buffers
@@ -124,8 +120,8 @@ hb_buffer_t::enlarge (unsigned int size)
}
unsigned int new_allocated = allocated;
- hb_glyph_position_t *new_pos = NULL;
- hb_glyph_info_t *new_info = NULL;
+ hb_glyph_position_t *new_pos = nullptr;
+ hb_glyph_info_t *new_info = nullptr;
bool separate_out = out_info != info;
if (unlikely (_hb_unsigned_int_mul_overflows (size, sizeof (info[0]))))
@@ -134,7 +130,7 @@ hb_buffer_t::enlarge (unsigned int size)
while (size >= new_allocated)
new_allocated += (new_allocated >> 1) + 32;
- ASSERT_STATIC (sizeof (info[0]) == sizeof (pos[0]));
+ static_assert ((sizeof (info[0]) == sizeof (pos[0])), "");
if (unlikely (_hb_unsigned_int_mul_overflows (new_allocated, sizeof (info[0]))))
goto done;
@@ -267,7 +263,7 @@ hb_buffer_t::add (hb_codepoint_t codepoint,
memset (glyph, 0, sizeof (*glyph));
glyph->codepoint = codepoint;
- glyph->mask = 1;
+ glyph->mask = 0;
glyph->cluster = cluster;
len++;
@@ -550,12 +546,15 @@ hb_buffer_t::merge_clusters_impl (unsigned int start,
unsigned int end)
{
if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS)
+ {
+ unsafe_to_break (start, end);
return;
+ }
unsigned int cluster = info[start].cluster;
for (unsigned int i = start + 1; i < end; i++)
- cluster = MIN (cluster, info[i].cluster);
+ cluster = MIN<unsigned int> (cluster, info[i].cluster);
/* Extend end */
while (end < len && info[end - 1].cluster == info[end].cluster)
@@ -568,10 +567,10 @@ hb_buffer_t::merge_clusters_impl (unsigned int start,
/* If we hit the start of buffer, continue in out-buffer. */
if (idx == start)
for (unsigned int i = out_len; i && out_info[i - 1].cluster == info[start].cluster; i--)
- out_info[i - 1].cluster = cluster;
+ set_cluster (out_info[i - 1], cluster);
for (unsigned int i = start; i < end; i++)
- info[i].cluster = cluster;
+ set_cluster (info[i], cluster);
}
void
hb_buffer_t::merge_out_clusters (unsigned int start,
@@ -586,7 +585,7 @@ hb_buffer_t::merge_out_clusters (unsigned int start,
unsigned int cluster = out_info[start].cluster;
for (unsigned int i = start + 1; i < end; i++)
- cluster = MIN (cluster, out_info[i].cluster);
+ cluster = MIN<unsigned int> (cluster, out_info[i].cluster);
/* Extend start */
while (start && out_info[start - 1].cluster == out_info[start].cluster)
@@ -599,14 +598,16 @@ hb_buffer_t::merge_out_clusters (unsigned int start,
/* If we hit the end of out-buffer, continue in buffer. */
if (end == out_len)
for (unsigned int i = idx; i < len && info[i].cluster == out_info[end - 1].cluster; i++)
- info[i].cluster = cluster;
+ set_cluster (info[i], cluster);
for (unsigned int i = start; i < end; i++)
- out_info[i].cluster = cluster;
+ set_cluster (out_info[i], cluster);
}
void
hb_buffer_t::delete_glyph ()
{
+ /* The logic here is duplicated in hb_ot_hide_default_ignorables(). */
+
unsigned int cluster = info[idx].cluster;
if (idx + 1 < len && cluster == info[idx + 1].cluster)
{
@@ -619,9 +620,10 @@ hb_buffer_t::delete_glyph ()
/* Merge cluster backward. */
if (cluster < out_info[out_len - 1].cluster)
{
+ unsigned int mask = info[idx].mask;
unsigned int old_cluster = out_info[out_len - 1].cluster;
for (unsigned i = out_len; i && out_info[i - 1].cluster == old_cluster; i--)
- out_info[i - 1].cluster = cluster;
+ set_cluster (out_info[i - 1], cluster, mask);
}
goto done;
}
@@ -638,6 +640,32 @@ done:
}
void
+hb_buffer_t::unsafe_to_break_impl (unsigned int start, unsigned int end)
+{
+ unsigned int cluster = (unsigned int) -1;
+ cluster = _unsafe_to_break_find_min_cluster (info, start, end, cluster);
+ _unsafe_to_break_set_mask (info, start, end, cluster);
+}
+void
+hb_buffer_t::unsafe_to_break_from_outbuffer (unsigned int start, unsigned int end)
+{
+ if (!have_output)
+ {
+ unsafe_to_break_impl (start, end);
+ return;
+ }
+
+ assert (start <= out_len);
+ assert (idx <= end);
+
+ unsigned int cluster = (unsigned int) -1;
+ cluster = _unsafe_to_break_find_min_cluster (out_info, start, out_len, cluster);
+ cluster = _unsafe_to_break_find_min_cluster (info, idx, end, cluster);
+ _unsafe_to_break_set_mask (out_info, start, out_len, cluster);
+ _unsafe_to_break_set_mask (info, idx, end, cluster);
+}
+
+void
hb_buffer_t::guess_segment_properties (void)
{
assert (content_type == HB_BUFFER_CONTENT_TYPE_UNICODE ||
@@ -694,6 +722,7 @@ hb_buffer_create (void)
return hb_buffer_get_empty ();
buffer->max_len = HB_BUFFER_MAX_LEN_DEFAULT;
+ buffer->max_ops = HB_BUFFER_MAX_OPS_DEFAULT;
buffer->reset ();
@@ -721,6 +750,7 @@ hb_buffer_get_empty (void)
HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT,
HB_BUFFER_SCRATCH_FLAG_DEFAULT,
HB_BUFFER_MAX_LEN_DEFAULT,
+ HB_BUFFER_MAX_OPS_DEFAULT,
HB_BUFFER_CONTENT_TYPE_INVALID,
HB_SEGMENT_PROPERTIES_DEFAULT,
@@ -1380,6 +1410,23 @@ hb_buffer_get_glyph_positions (hb_buffer_t *buffer,
}
/**
+ * hb_glyph_info_get_glyph_flags:
+ * @info: a #hb_glyph_info_t.
+ *
+ * Returns glyph flags encoded within a #hb_glyph_info_t.
+ *
+ * Return value:
+ * The #hb_glyph_flags_t encoded within @info.
+ *
+ * Since: 1.5.0
+ **/
+hb_glyph_flags_t
+(hb_glyph_info_get_glyph_flags) (const hb_glyph_info_t *info)
+{
+ return hb_glyph_info_get_glyph_flags (info);
+}
+
+/**
* hb_buffer_reverse:
* @buffer: an #hb_buffer_t.
*
@@ -1666,6 +1713,58 @@ hb_buffer_add_codepoints (hb_buffer_t *buffer,
}
+/**
+ * hb_buffer_append:
+ * @buffer: an #hb_buffer_t.
+ * @source: source #hb_buffer_t.
+ * @start: start index into source buffer to copy. Use 0 to copy from start of buffer.
+ * @end: end index into source buffer to copy. Use (unsigned int) -1 to copy to end of buffer.
+ *
+ * Append (part of) contents of another buffer to this buffer.
+ *
+ * Since: 1.5.0
+ **/
+HB_EXTERN void
+hb_buffer_append (hb_buffer_t *buffer,
+ hb_buffer_t *source,
+ unsigned int start,
+ unsigned int end)
+{
+ assert (!buffer->have_output && !source->have_output);
+ assert (buffer->have_positions == source->have_positions ||
+ !buffer->len || !source->len);
+ assert (buffer->content_type == source->content_type ||
+ !buffer->len || !source->len);
+
+ if (end > source->len)
+ end = source->len;
+ if (start > end)
+ start = end;
+ if (start == end)
+ return;
+
+ if (!buffer->len)
+ buffer->content_type = source->content_type;
+ if (!buffer->have_positions && source->have_positions)
+ buffer->clear_positions ();
+
+ if (buffer->len + (end - start) < buffer->len) /* Overflows. */
+ {
+ buffer->in_error = true;
+ return;
+ }
+
+ unsigned int orig_len = buffer->len;
+ hb_buffer_set_length (buffer, buffer->len + (end - start));
+ if (buffer->in_error)
+ return;
+
+ memcpy (buffer->info + orig_len, source->info + start, (end - start) * sizeof (buffer->info[0]));
+ if (buffer->have_positions)
+ memcpy (buffer->pos + orig_len, source->pos + start, (end - start) * sizeof (buffer->pos[0]));
+}
+
+
static int
compare_info_codepoint (const hb_glyph_info_t *pa,
const hb_glyph_info_t *pb)
@@ -1736,7 +1835,8 @@ void
hb_buffer_normalize_glyphs (hb_buffer_t *buffer)
{
assert (buffer->have_positions);
- assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS);
+ assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS ||
+ (!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID));
bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
@@ -1775,6 +1875,98 @@ hb_buffer_t::sort (unsigned int start, unsigned int end, int(*compar)(const hb_g
}
}
+
+/*
+ * Comparing buffers.
+ */
+
+/**
+ * hb_buffer_diff:
+ *
+ * If dottedcircle_glyph is (hb_codepoint_t) -1 then %HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT
+ * and %HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT are never returned. This should be used by most
+ * callers if just comparing two buffers is needed.
+ *
+ * Since: 1.5.0
+ **/
+hb_buffer_diff_flags_t
+hb_buffer_diff (hb_buffer_t *buffer,
+ hb_buffer_t *reference,
+ hb_codepoint_t dottedcircle_glyph,
+ unsigned int position_fuzz)
+{
+ if (buffer->content_type != reference->content_type && buffer->len && reference->len)
+ return HB_BUFFER_DIFF_FLAG_CONTENT_TYPE_MISMATCH;
+
+ hb_buffer_diff_flags_t result = HB_BUFFER_DIFF_FLAG_EQUAL;
+ bool contains = dottedcircle_glyph != (hb_codepoint_t) -1;
+
+ unsigned int count = reference->len;
+
+ if (buffer->len != count)
+ {
+ /*
+ * we can't compare glyph-by-glyph, but we do want to know if there
+ * are .notdef or dottedcircle glyphs present in the reference buffer
+ */
+ const hb_glyph_info_t *info = reference->info;
+ unsigned int i;
+ for (i = 0; i < count; i++)
+ {
+ if (contains && info[i].codepoint == dottedcircle_glyph)
+ result |= HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT;
+ if (contains && info[i].codepoint == 0)
+ result |= HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT;
+ }
+ result |= HB_BUFFER_DIFF_FLAG_LENGTH_MISMATCH;
+ return hb_buffer_diff_flags_t (result);
+ }
+
+ if (!count)
+ return hb_buffer_diff_flags_t (result);
+
+ const hb_glyph_info_t *buf_info = buffer->info;
+ const hb_glyph_info_t *ref_info = reference->info;
+ for (unsigned int i = 0; i < count; i++)
+ {
+ if (buf_info->codepoint != ref_info->codepoint)
+ result |= HB_BUFFER_DIFF_FLAG_CODEPOINT_MISMATCH;
+ if (buf_info->cluster != ref_info->cluster)
+ result |= HB_BUFFER_DIFF_FLAG_CLUSTER_MISMATCH;
+ if ((buf_info->mask & HB_GLYPH_FLAG_DEFINED) != (ref_info->mask & HB_GLYPH_FLAG_DEFINED))
+ result |= HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH;
+ if (contains && ref_info->codepoint == dottedcircle_glyph)
+ result |= HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT;
+ if (contains && ref_info->codepoint == 0)
+ result |= HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT;
+ buf_info++;
+ ref_info++;
+ }
+
+ if (buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS)
+ {
+ assert (buffer->have_positions);
+ const hb_glyph_position_t *buf_pos = buffer->pos;
+ const hb_glyph_position_t *ref_pos = reference->pos;
+ for (unsigned int i = 0; i < count; i++)
+ {
+ if ((unsigned int) abs (buf_pos->x_advance - ref_pos->x_advance) > position_fuzz ||
+ (unsigned int) abs (buf_pos->y_advance - ref_pos->y_advance) > position_fuzz ||
+ (unsigned int) abs (buf_pos->x_offset - ref_pos->x_offset) > position_fuzz ||
+ (unsigned int) abs (buf_pos->y_offset - ref_pos->y_offset) > position_fuzz)
+ {
+ result |= HB_BUFFER_DIFF_FLAG_POSITION_MISMATCH;
+ break;
+ }
+ buf_pos++;
+ ref_pos++;
+ }
+ }
+
+ return result;
+}
+
+
/*
* Debugging.
*/
@@ -1803,9 +1995,9 @@ hb_buffer_set_message_func (hb_buffer_t *buffer,
buffer->message_data = user_data;
buffer->message_destroy = destroy;
} else {
- buffer->message_func = NULL;
- buffer->message_data = NULL;
- buffer->message_destroy = NULL;
+ buffer->message_func = nullptr;
+ buffer->message_data = nullptr;
+ buffer->message_destroy = nullptr;
}
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.h b/src/3rdparty/harfbuzz-ng/src/hb-buffer.h
index bf289c19b3..a8a4b84e97 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-buffer.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer.h
@@ -63,7 +63,7 @@ HB_BEGIN_DECLS
*/
typedef struct hb_glyph_info_t {
hb_codepoint_t codepoint;
- hb_mask_t mask;
+ hb_mask_t mask; /* Holds hb_glyph_flags_t after hb_shape(), plus other things. */
uint32_t cluster;
/*< private >*/
@@ -71,6 +71,19 @@ typedef struct hb_glyph_info_t {
hb_var_int_t var2;
} hb_glyph_info_t;
+typedef enum { /*< flags >*/
+ HB_GLYPH_FLAG_UNSAFE_TO_BREAK = 0x00000001,
+
+ HB_GLYPH_FLAG_DEFINED = 0x00000001 /* OR of all defined flags */
+} hb_glyph_flags_t;
+
+HB_EXTERN hb_glyph_flags_t
+hb_glyph_info_get_glyph_flags (const hb_glyph_info_t *info);
+
+#define hb_glyph_info_get_glyph_flags(info) \
+ ((hb_glyph_flags_t) ((unsigned int) (info)->mask & HB_GLYPH_FLAG_DEFINED))
+
+
/**
* hb_glyph_position_t:
* @x_advance: how much the line advances after drawing this glyph when setting
@@ -119,8 +132,8 @@ typedef struct hb_segment_properties_t {
#define HB_SEGMENT_PROPERTIES_DEFAULT {HB_DIRECTION_INVALID, \
HB_SCRIPT_INVALID, \
HB_LANGUAGE_INVALID, \
- NULL, \
- NULL}
+ (void *) 0, \
+ (void *) 0}
HB_EXTERN hb_bool_t
hb_segment_properties_equal (const hb_segment_properties_t *a,
@@ -163,6 +176,7 @@ HB_EXTERN void *
hb_buffer_get_user_data (hb_buffer_t *buffer,
hb_user_data_key_t *key);
+
/**
* hb_buffer_content_type_t:
* @HB_BUFFER_CONTENT_TYPE_INVALID: Initial value for new buffer.
@@ -359,6 +373,11 @@ hb_buffer_add_codepoints (hb_buffer_t *buffer,
unsigned int item_offset,
int item_length);
+HB_EXTERN void
+hb_buffer_append (hb_buffer_t *buffer,
+ hb_buffer_t *source,
+ unsigned int start,
+ unsigned int end);
HB_EXTERN hb_bool_t
hb_buffer_set_length (hb_buffer_t *buffer,
@@ -403,7 +422,8 @@ typedef enum { /*< flags >*/
HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS = 0x00000001u,
HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS = 0x00000002u,
HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES = 0x00000004u,
- HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS = 0x00000008u
+ HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS = 0x00000008u,
+ HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS = 0x00000010u
} hb_buffer_serialize_flags_t;
/**
@@ -453,6 +473,45 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
/*
+ * Compare buffers
+ */
+
+typedef enum { /*< flags >*/
+ HB_BUFFER_DIFF_FLAG_EQUAL = 0x0000,
+
+ /* Buffers with different content_type cannot be meaningfully compared
+ * in any further detail. */
+ HB_BUFFER_DIFF_FLAG_CONTENT_TYPE_MISMATCH = 0x0001,
+
+ /* For buffers with differing length, the per-glyph comparison is not
+ * attempted, though we do still scan reference for dottedcircle / .notdef
+ * glyphs. */
+ HB_BUFFER_DIFF_FLAG_LENGTH_MISMATCH = 0x0002,
+
+ /* We want to know if dottedcircle / .notdef glyphs are present in the
+ * reference, as we may not care so much about other differences in this
+ * case. */
+ HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT = 0x0004,
+ HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT = 0x0008,
+
+ /* If the buffers have the same length, we compare them glyph-by-glyph
+ * and report which aspect(s) of the glyph info/position are different. */
+ HB_BUFFER_DIFF_FLAG_CODEPOINT_MISMATCH = 0x0010,
+ HB_BUFFER_DIFF_FLAG_CLUSTER_MISMATCH = 0x0020,
+ HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH = 0x0040,
+ HB_BUFFER_DIFF_FLAG_POSITION_MISMATCH = 0x0080
+
+} hb_buffer_diff_flags_t;
+
+/* Compare the contents of two buffers, report types of differences. */
+HB_EXTERN hb_buffer_diff_flags_t
+hb_buffer_diff (hb_buffer_t *buffer,
+ hb_buffer_t *reference,
+ hb_codepoint_t dottedcircle_glyph,
+ unsigned int position_fuzz);
+
+
+/*
* Debugging.
*/
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-common.cc b/src/3rdparty/harfbuzz-ng/src/hb-common.cc
index 3564e43557..cb1fb43ffb 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-common.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-common.cc
@@ -32,6 +32,9 @@
#include "hb-object-private.hh"
#include <locale.h>
+#ifdef HAVE_XLOCALE_H
+#include <xlocale.h>
+#endif
/* hb_options_t */
@@ -82,7 +85,7 @@ hb_tag_from_string (const char *str, int len)
for (; i < 4; i++)
tag[i] = ' ';
- return HB_TAG_CHAR4 (tag);
+ return HB_TAG (tag[0], tag[1], tag[2], tag[3]);
}
/**
@@ -186,8 +189,10 @@ lang_equal (hb_language_t v1,
const unsigned char *p1 = (const unsigned char *) v1;
const unsigned char *p2 = (const unsigned char *) v2;
- while (*p1 && *p1 == canon_map[*p2])
- p1++, p2++;
+ while (*p1 && *p1 == canon_map[*p2]) {
+ p1++;
+ p2++;
+ }
return *p1 == canon_map[*p2];
}
@@ -219,9 +224,18 @@ struct hb_language_item_t {
}
inline hb_language_item_t & operator = (const char *s) {
- lang = (hb_language_t) strdup (s);
- for (unsigned char *p = (unsigned char *) lang; *p; p++)
- *p = canon_map[*p];
+ /* If a custom allocated is used calling strdup() pairs
+ badly with a call to the custom free() in finish() below.
+ Therefore don't call strdup(), implement its behavior.
+ */
+ size_t len = strlen(s) + 1;
+ lang = (hb_language_t) malloc(len);
+ if (likely (lang))
+ {
+ memcpy((unsigned char *) lang, s, len);
+ for (unsigned char *p = (unsigned char *) lang; *p; p++)
+ *p = canon_map[*p];
+ }
return *this;
}
@@ -235,8 +249,8 @@ struct hb_language_item_t {
static hb_language_item_t *langs;
#ifdef HB_USE_ATEXIT
-static
-void free_langs (void)
+static void
+free_langs (void)
{
while (langs) {
hb_language_item_t *next = langs->next;
@@ -260,9 +274,14 @@ retry:
/* Not found; allocate one. */
hb_language_item_t *lang = (hb_language_item_t *) calloc (1, sizeof (hb_language_item_t));
if (unlikely (!lang))
- return NULL;
+ return nullptr;
lang->next = first_lang;
*lang = key;
+ if (unlikely (!lang->lang))
+ {
+ free (lang);
+ return nullptr;
+ }
if (!hb_atomic_ptr_cmpexch (&langs, first_lang, lang)) {
lang->finish ();
@@ -299,7 +318,7 @@ hb_language_from_string (const char *str, int len)
if (!str || !len || !*str)
return HB_LANGUAGE_INVALID;
- hb_language_item_t *item = NULL;
+ hb_language_item_t *item = nullptr;
if (len >= 0)
{
/* NUL-terminate it. */
@@ -330,7 +349,7 @@ hb_language_from_string (const char *str, int len)
const char *
hb_language_to_string (hb_language_t language)
{
- /* This is actually NULL-safe! */
+ /* This is actually nullptr-safe! */
return language->s;
}
@@ -350,7 +369,7 @@ hb_language_get_default (void)
hb_language_t language = (hb_language_t) hb_atomic_ptr_get (&default_language);
if (unlikely (language == HB_LANGUAGE_INVALID)) {
- language = hb_language_from_string (setlocale (LC_CTYPE, NULL), -1);
+ language = hb_language_from_string (setlocale (LC_CTYPE, nullptr), -1);
(void) hb_atomic_ptr_cmpexch (&default_language, HB_LANGUAGE_INVALID, language);
}
@@ -543,9 +562,9 @@ hb_user_data_array_t::set (hb_user_data_key_t *key,
void *
hb_user_data_array_t::get (hb_user_data_key_t *key)
{
- hb_user_data_item_t item = {NULL, NULL, NULL};
+ hb_user_data_item_t item = {nullptr, nullptr, nullptr};
- return items.find (key, &item, lock) ? item.data : NULL;
+ return items.find (key, &item, lock) ? item.data : nullptr;
}
@@ -605,3 +624,426 @@ hb_version_atleast (unsigned int major,
{
return HB_VERSION_ATLEAST (major, minor, micro);
}
+
+
+
+/* hb_feature_t and hb_variation_t */
+
+static bool
+parse_space (const char **pp, const char *end)
+{
+ while (*pp < end && ISSPACE (**pp))
+ (*pp)++;
+ return true;
+}
+
+static bool
+parse_char (const char **pp, const char *end, char c)
+{
+ parse_space (pp, end);
+
+ if (*pp == end || **pp != c)
+ return false;
+
+ (*pp)++;
+ return true;
+}
+
+static bool
+parse_uint (const char **pp, const char *end, unsigned int *pv)
+{
+ char buf[32];
+ unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp));
+ strncpy (buf, *pp, len);
+ buf[len] = '\0';
+
+ char *p = buf;
+ char *pend = p;
+ unsigned int v;
+
+ /* Intentionally use strtol instead of strtoul, such that
+ * -1 turns into "big number"... */
+ errno = 0;
+ v = strtol (p, &pend, 0);
+ if (errno || p == pend)
+ return false;
+
+ *pv = v;
+ *pp += pend - p;
+ return true;
+}
+
+static bool
+parse_uint32 (const char **pp, const char *end, uint32_t *pv)
+{
+ char buf[32];
+ unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp));
+ strncpy (buf, *pp, len);
+ buf[len] = '\0';
+
+ char *p = buf;
+ char *pend = p;
+ unsigned int v;
+
+ /* Intentionally use strtol instead of strtoul, such that
+ * -1 turns into "big number"... */
+ errno = 0;
+ v = strtol (p, &pend, 0);
+ if (errno || p == pend)
+ return false;
+
+ *pv = v;
+ *pp += pend - p;
+ return true;
+}
+
+#if defined (HAVE_NEWLOCALE) && defined (HAVE_STRTOD_L)
+#define USE_XLOCALE 1
+#define HB_LOCALE_T locale_t
+#define HB_CREATE_LOCALE(locName) newlocale (LC_ALL_MASK, locName, nullptr)
+#define HB_FREE_LOCALE(loc) freelocale (loc)
+#elif defined(_MSC_VER)
+#define USE_XLOCALE 1
+#define HB_LOCALE_T _locale_t
+#define HB_CREATE_LOCALE(locName) _create_locale (LC_ALL, locName)
+#define HB_FREE_LOCALE(loc) _free_locale (loc)
+#define strtod_l(a, b, c) _strtod_l ((a), (b), (c))
+#endif
+
+#ifdef USE_XLOCALE
+
+static HB_LOCALE_T C_locale;
+
+#ifdef HB_USE_ATEXIT
+static void
+free_C_locale (void)
+{
+ if (C_locale)
+ HB_FREE_LOCALE (C_locale);
+}
+#endif
+
+static HB_LOCALE_T
+get_C_locale (void)
+{
+retry:
+ HB_LOCALE_T C = (HB_LOCALE_T) hb_atomic_ptr_get (&C_locale);
+
+ if (unlikely (!C))
+ {
+ C = HB_CREATE_LOCALE ("C");
+
+ if (!hb_atomic_ptr_cmpexch (&C_locale, nullptr, C))
+ {
+ HB_FREE_LOCALE (C_locale);
+ goto retry;
+ }
+
+#ifdef HB_USE_ATEXIT
+ atexit (free_C_locale); /* First person registers atexit() callback. */
+#endif
+ }
+
+ return C;
+}
+#endif
+
+static bool
+parse_float (const char **pp, const char *end, float *pv)
+{
+ char buf[32];
+ unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp));
+ strncpy (buf, *pp, len);
+ buf[len] = '\0';
+
+ char *p = buf;
+ char *pend = p;
+ float v;
+
+ errno = 0;
+#ifdef USE_XLOCALE
+ v = strtod_l (p, &pend, get_C_locale ());
+#else
+ v = strtod (p, &pend);
+#endif
+ if (errno || p == pend)
+ return false;
+
+ *pv = v;
+ *pp += pend - p;
+ return true;
+}
+
+static bool
+parse_bool (const char **pp, const char *end, uint32_t *pv)
+{
+ parse_space (pp, end);
+
+ const char *p = *pp;
+ while (*pp < end && ISALPHA(**pp))
+ (*pp)++;
+
+ /* CSS allows on/off as aliases 1/0. */
+ if (*pp - p == 2 && 0 == strncmp (p, "on", 2))
+ *pv = 1;
+ else if (*pp - p == 3 && 0 == strncmp (p, "off", 3))
+ *pv = 0;
+ else
+ return false;
+
+ return true;
+}
+
+/* hb_feature_t */
+
+static bool
+parse_feature_value_prefix (const char **pp, const char *end, hb_feature_t *feature)
+{
+ if (parse_char (pp, end, '-'))
+ feature->value = 0;
+ else {
+ parse_char (pp, end, '+');
+ feature->value = 1;
+ }
+
+ return true;
+}
+
+static bool
+parse_tag (const char **pp, const char *end, hb_tag_t *tag)
+{
+ parse_space (pp, end);
+
+ char quote = 0;
+
+ if (*pp < end && (**pp == '\'' || **pp == '"'))
+ {
+ quote = **pp;
+ (*pp)++;
+ }
+
+ const char *p = *pp;
+ while (*pp < end && ISALNUM(**pp))
+ (*pp)++;
+
+ if (p == *pp || *pp - p > 4)
+ return false;
+
+ *tag = hb_tag_from_string (p, *pp - p);
+
+ if (quote)
+ {
+ /* CSS expects exactly four bytes. And we only allow quotations for
+ * CSS compatibility. So, enforce the length. */
+ if (*pp - p != 4)
+ return false;
+ if (*pp == end || **pp != quote)
+ return false;
+ (*pp)++;
+ }
+
+ return true;
+}
+
+static bool
+parse_feature_indices (const char **pp, const char *end, hb_feature_t *feature)
+{
+ parse_space (pp, end);
+
+ bool has_start;
+
+ feature->start = 0;
+ feature->end = (unsigned int) -1;
+
+ if (!parse_char (pp, end, '['))
+ return true;
+
+ has_start = parse_uint (pp, end, &feature->start);
+
+ if (parse_char (pp, end, ':')) {
+ parse_uint (pp, end, &feature->end);
+ } else {
+ if (has_start)
+ feature->end = feature->start + 1;
+ }
+
+ return parse_char (pp, end, ']');
+}
+
+static bool
+parse_feature_value_postfix (const char **pp, const char *end, hb_feature_t *feature)
+{
+ bool had_equal = parse_char (pp, end, '=');
+ bool had_value = parse_uint32 (pp, end, &feature->value) ||
+ parse_bool (pp, end, &feature->value);
+ /* CSS doesn't use equal-sign between tag and value.
+ * If there was an equal-sign, then there *must* be a value.
+ * A value without an eqaul-sign is ok, but not required. */
+ return !had_equal || had_value;
+}
+
+static bool
+parse_one_feature (const char **pp, const char *end, hb_feature_t *feature)
+{
+ return parse_feature_value_prefix (pp, end, feature) &&
+ parse_tag (pp, end, &feature->tag) &&
+ parse_feature_indices (pp, end, feature) &&
+ parse_feature_value_postfix (pp, end, feature) &&
+ parse_space (pp, end) &&
+ *pp == end;
+}
+
+/**
+ * hb_feature_from_string:
+ * @str: (array length=len) (element-type uint8_t): a string to parse
+ * @len: length of @str, or -1 if string is %NULL terminated
+ * @feature: (out): the #hb_feature_t to initialize with the parsed values
+ *
+ * Parses a string into a #hb_feature_t.
+ *
+ * TODO: document the syntax here.
+ *
+ * Return value:
+ * %true if @str is successfully parsed, %false otherwise.
+ *
+ * Since: 0.9.5
+ **/
+hb_bool_t
+hb_feature_from_string (const char *str, int len,
+ hb_feature_t *feature)
+{
+ hb_feature_t feat;
+
+ if (len < 0)
+ len = strlen (str);
+
+ if (likely (parse_one_feature (&str, str + len, &feat)))
+ {
+ if (feature)
+ *feature = feat;
+ return true;
+ }
+
+ if (feature)
+ memset (feature, 0, sizeof (*feature));
+ return false;
+}
+
+/**
+ * hb_feature_to_string:
+ * @feature: an #hb_feature_t to convert
+ * @buf: (array length=size) (out): output string
+ * @size: the allocated size of @buf
+ *
+ * Converts a #hb_feature_t into a %NULL-terminated string in the format
+ * understood by hb_feature_from_string(). The client in responsible for
+ * allocating big enough size for @buf, 128 bytes is more than enough.
+ *
+ * Since: 0.9.5
+ **/
+void
+hb_feature_to_string (hb_feature_t *feature,
+ char *buf, unsigned int size)
+{
+ if (unlikely (!size)) return;
+
+ char s[128];
+ unsigned int len = 0;
+ if (feature->value == 0)
+ s[len++] = '-';
+ hb_tag_to_string (feature->tag, s + len);
+ len += 4;
+ while (len && s[len - 1] == ' ')
+ len--;
+ if (feature->start != 0 || feature->end != (unsigned int) -1)
+ {
+ s[len++] = '[';
+ if (feature->start)
+ len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->start));
+ if (feature->end != feature->start + 1) {
+ s[len++] = ':';
+ if (feature->end != (unsigned int) -1)
+ len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->end));
+ }
+ s[len++] = ']';
+ }
+ if (feature->value > 1)
+ {
+ s[len++] = '=';
+ len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->value));
+ }
+ assert (len < ARRAY_LENGTH (s));
+ len = MIN (len, size - 1);
+ memcpy (buf, s, len);
+ buf[len] = '\0';
+}
+
+/* hb_variation_t */
+
+static bool
+parse_variation_value (const char **pp, const char *end, hb_variation_t *variation)
+{
+ parse_char (pp, end, '='); /* Optional. */
+ return parse_float (pp, end, &variation->value);
+}
+
+static bool
+parse_one_variation (const char **pp, const char *end, hb_variation_t *variation)
+{
+ return parse_tag (pp, end, &variation->tag) &&
+ parse_variation_value (pp, end, variation) &&
+ parse_space (pp, end) &&
+ *pp == end;
+}
+
+/**
+ * hb_variation_from_string:
+ *
+ * Since: 1.4.2
+ */
+hb_bool_t
+hb_variation_from_string (const char *str, int len,
+ hb_variation_t *variation)
+{
+ hb_variation_t var;
+
+ if (len < 0)
+ len = strlen (str);
+
+ if (likely (parse_one_variation (&str, str + len, &var)))
+ {
+ if (variation)
+ *variation = var;
+ return true;
+ }
+
+ if (variation)
+ memset (variation, 0, sizeof (*variation));
+ return false;
+}
+
+/**
+ * hb_variation_to_string:
+ *
+ * Since: 1.4.2
+ */
+void
+hb_variation_to_string (hb_variation_t *variation,
+ char *buf, unsigned int size)
+{
+ if (unlikely (!size)) return;
+
+ char s[128];
+ unsigned int len = 0;
+ hb_tag_to_string (variation->tag, s + len);
+ len += 4;
+ while (len && s[len - 1] == ' ')
+ len--;
+ s[len++] = '=';
+ len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%g", variation->value));
+
+ assert (len < ARRAY_LENGTH (s));
+ len = MIN (len, size - 1);
+ memcpy (buf, s, len);
+ buf[len] = '\0';
+}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-common.h b/src/3rdparty/harfbuzz-ng/src/hb-common.h
index 2cbee76a8f..26200ce125 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-common.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-common.h
@@ -43,30 +43,16 @@
# endif /* !__cplusplus */
#endif
-#if !defined (HB_DONT_DEFINE_STDINT)
-
#if defined (_SVR4) || defined (SVR4) || defined (__OpenBSD__) || \
defined (_sgi) || defined (__sun) || defined (sun) || \
defined (__digital__) || defined (__HP_cc)
# include <inttypes.h>
#elif defined (_AIX)
# include <sys/inttypes.h>
-/* VS 2010 (_MSC_VER 1600) has stdint.h */
-#elif defined (_MSC_VER) && _MSC_VER < 1600
-typedef __int8 int8_t;
-typedef unsigned __int8 uint8_t;
-typedef __int16 int16_t;
-typedef unsigned __int16 uint16_t;
-typedef __int32 int32_t;
-typedef unsigned __int32 uint32_t;
-typedef __int64 int64_t;
-typedef unsigned __int64 uint64_t;
#else
# include <stdint.h>
#endif
-#endif
-
HB_BEGIN_DECLS
@@ -148,7 +134,7 @@ hb_language_from_string (const char *str, int len);
HB_EXTERN const char *
hb_language_to_string (hb_language_t language);
-#define HB_LANGUAGE_INVALID ((hb_language_t) NULL)
+#define HB_LANGUAGE_INVALID ((hb_language_t) 0)
HB_EXTERN hb_language_t
hb_language_get_default (void);
@@ -321,6 +307,14 @@ typedef enum
/*9.0*/ HB_SCRIPT_TANGUT = HB_TAG ('T','a','n','g'),
/*9.0*/ HB_SCRIPT_NEWA = HB_TAG ('N','e','w','a'),
+ /*
+ * Since 1.6.0
+ */
+ /*10.0*/HB_SCRIPT_MASARAM_GONDI = HB_TAG ('G','o','n','m'),
+ /*10.0*/HB_SCRIPT_NUSHU = HB_TAG ('N','s','h','u'),
+ /*10.0*/HB_SCRIPT_SOYOMBO = HB_TAG ('S','o','y','o'),
+ /*10.0*/HB_SCRIPT_ZANABAZAR_SQUARE = HB_TAG ('Z','a','n','b'),
+
/* No script set. */
HB_SCRIPT_INVALID = HB_TAG_NONE,
@@ -362,6 +356,42 @@ typedef struct hb_user_data_key_t {
typedef void (*hb_destroy_func_t) (void *user_data);
+/* Font features and variations. */
+
+typedef struct hb_feature_t {
+ hb_tag_t tag;
+ uint32_t value;
+ unsigned int start;
+ unsigned int end;
+} hb_feature_t;
+
+HB_EXTERN hb_bool_t
+hb_feature_from_string (const char *str, int len,
+ hb_feature_t *feature);
+
+HB_EXTERN void
+hb_feature_to_string (hb_feature_t *feature,
+ char *buf, unsigned int size);
+
+/**
+ * hb_variation_t:
+ *
+ * Since: 1.4.2
+ */
+typedef struct hb_variation_t {
+ hb_tag_t tag;
+ float value;
+} hb_variation_t;
+
+HB_EXTERN hb_bool_t
+hb_variation_from_string (const char *str, int len,
+ hb_variation_t *variation);
+
+HB_EXTERN void
+hb_variation_to_string (hb_variation_t *variation,
+ char *buf, unsigned int size);
+
+
HB_END_DECLS
#endif /* HB_COMMON_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc
index 9865bbba41..9431ba5fe1 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc
@@ -27,14 +27,13 @@
*/
#define HB_SHAPER coretext
+
+#include "hb-private.hh"
+#include "hb-debug.hh"
#include "hb-shaper-impl-private.hh"
#include "hb-coretext.h"
-
-
-#ifndef HB_DEBUG_CORETEXT
-#define HB_DEBUG_CORETEXT (HB_DEBUG+0)
-#endif
+#include <math.h>
typedef bool (*qt_get_font_table_func_t) (void *user_data, unsigned int tag, unsigned char *buffer, unsigned int *length);
@@ -50,6 +49,27 @@ struct CoreTextFontEngineData {
};
+/* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */
+#define HB_CORETEXT_DEFAULT_FONT_SIZE 12.f
+
+static CGFloat
+coretext_font_size_from_ptem (float ptem)
+{
+ /* CoreText points are CSS pixels (96 per inch),
+ * NOT typographic points (72 per inch).
+ *
+ * https://developer.apple.com/library/content/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html
+ */
+ ptem *= 96.f / 72.f;
+ return ptem <= 0.f ? HB_CORETEXT_DEFAULT_FONT_SIZE : ptem;
+}
+static float
+coretext_font_size_to_ptem (CGFloat size)
+{
+ size *= 72.f / 96.f;
+ return size <= 0.f ? 0 : size;
+}
+
static void
release_table_data (void *user_data)
{
@@ -63,32 +83,29 @@ reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
CGFontRef cg_font = reinterpret_cast<CGFontRef> (user_data);
CFDataRef cf_data = CGFontCopyTableForTag (cg_font, tag);
if (unlikely (!cf_data))
- return NULL;
+ return nullptr;
const char *data = reinterpret_cast<const char*> (CFDataGetBytePtr (cf_data));
const size_t length = CFDataGetLength (cf_data);
if (!data || !length)
- return NULL;
+ return nullptr;
return hb_blob_create (data, length, HB_MEMORY_MODE_READONLY,
reinterpret_cast<void *> (const_cast<__CFData *> (cf_data)),
release_table_data);
}
-hb_face_t *
-hb_coretext_face_create (CGFontRef cg_font)
+static void
+_hb_cg_font_release (void *data)
{
- return hb_face_create_for_tables (reference_table, CGFontRetain (cg_font), (hb_destroy_func_t) CGFontRelease);
+ CGFontRelease ((CGFontRef) data);
}
-HB_SHAPER_DATA_ENSURE_DECLARE(coretext, face)
-HB_SHAPER_DATA_ENSURE_DECLARE(coretext, font)
-
-
-/*
- * shaper face data
- */
+HB_SHAPER_DATA_ENSURE_DEFINE(coretext, face)
+HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(coretext, font,
+ fabs (CTFontGetSize((CTFontRef) data) - coretext_font_size_from_ptem (font->ptem)) <= .5
+)
static CTFontDescriptorRef
get_last_resort_font_desc (void)
@@ -117,7 +134,7 @@ static void
release_data (void *info, const void *data, size_t size)
{
assert (hb_blob_get_length ((hb_blob_t *) info) == size &&
- hb_blob_get_data ((hb_blob_t *) info, NULL) == data);
+ hb_blob_get_data ((hb_blob_t *) info, nullptr) == data);
hb_blob_destroy ((hb_blob_t *) info);
}
@@ -125,14 +142,14 @@ release_data (void *info, const void *data, size_t size)
static CGFontRef
create_cg_font (hb_face_t *face)
{
- CGFontRef cg_font = NULL;
-#if 0
- if (face->destroy == (hb_destroy_func_t) CGFontRelease)
+ CGFontRef cg_font = nullptr;
+ if (face->destroy == _hb_cg_font_release)
{
cg_font = CGFontRetain ((CGFontRef) face->user_data);
}
else
{
+#if 0
hb_blob_t *blob = hb_face_reference_blob (face);
unsigned int blob_length;
const char *blob_data = hb_blob_get_data (blob, &blob_length);
@@ -147,22 +164,48 @@ create_cg_font (hb_face_t *face)
DEBUG_MSG (CORETEXT, face, "Face CGFontCreateWithDataProvider() failed");
CGDataProviderRelease (provider);
}
- }
#else
- FontEngineFaceData *fontEngineFaceData = (FontEngineFaceData *) face->user_data;
- CoreTextFontEngineData *coreTextFontEngineData = (CoreTextFontEngineData *) fontEngineFaceData->user_data;
- cg_font = CGFontRetain (coreTextFontEngineData->cgFont);
+ FontEngineFaceData *fontEngineFaceData = (FontEngineFaceData *) face->user_data;
+ CoreTextFontEngineData *coreTextFontEngineData = (CoreTextFontEngineData *) fontEngineFaceData->user_data;
+ cg_font = CGFontRetain (coreTextFontEngineData->cgFont);
#endif
+ }
return cg_font;
}
static CTFontRef
create_ct_font (CGFontRef cg_font, CGFloat font_size)
{
- CTFontRef ct_font = CTFontCreateWithGraphicsFont (cg_font, font_size, NULL, NULL);
+ CTFontRef ct_font = nullptr;
+
+ /* CoreText does not enable trak table usage / tracking when creating a CTFont
+ * using CTFontCreateWithGraphicsFont. The only way of enabling tracking seems
+ * to be through the CTFontCreateUIFontForLanguage call. */
+ CFStringRef cg_postscript_name = CGFontCopyPostScriptName (cg_font);
+ if (CFStringHasPrefix (cg_postscript_name, CFSTR (".SFNSText")) ||
+ CFStringHasPrefix (cg_postscript_name, CFSTR (".SFNSDisplay")))
+ {
+ CTFontUIFontType font_type = kCTFontUIFontSystem;
+ if (CFStringHasSuffix (cg_postscript_name, CFSTR ("-Bold")))
+ font_type = kCTFontUIFontEmphasizedSystem;
+
+ ct_font = CTFontCreateUIFontForLanguage (font_type, font_size, nullptr);
+ CFStringRef ct_result_name = CTFontCopyPostScriptName(ct_font);
+ if (CFStringCompare (ct_result_name, cg_postscript_name, 0) != kCFCompareEqualTo)
+ {
+ CFRelease(ct_font);
+ ct_font = nullptr;
+ }
+ CFRelease (ct_result_name);
+ }
+ CFRelease (cg_postscript_name);
+
+ if (!ct_font)
+ ct_font = CTFontCreateWithGraphicsFont (cg_font, font_size, nullptr, nullptr);
+
if (unlikely (!ct_font)) {
DEBUG_MSG (CORETEXT, cg_font, "Font CTFontCreateWithGraphicsFont() failed");
- return NULL;
+ return nullptr;
}
/* crbug.com/576941 and crbug.com/625902 and the investigation in the latter
@@ -172,7 +215,7 @@ create_ct_font (CGFontRef cg_font, CGFloat font_size)
* reconfiguring the cascade list causes CoreText crashes. For details, see
* crbug.com/549610 */
// 0x00070000 stands for "kCTVersionNumber10_10", see CoreText.h
- if (&CTGetCoreTextVersion != NULL && CTGetCoreTextVersion() < 0x00070000) {
+ if (&CTGetCoreTextVersion != nullptr && CTGetCoreTextVersion() < 0x00070000) {
CFStringRef fontName = CTFontCopyPostScriptName (ct_font);
bool isEmojiFont = CFStringCompare (fontName, CFSTR("AppleColorEmoji"), 0) == kCFCompareEqualTo;
CFRelease (fontName);
@@ -186,7 +229,7 @@ create_ct_font (CGFontRef cg_font, CGFloat font_size)
* font fallback which we don't need anyway. */
{
CTFontDescriptorRef last_resort_font_desc = get_last_resort_font_desc ();
- CTFontRef new_ct_font = CTFontCreateCopyWithAttributes (ct_font, 0.0, NULL, last_resort_font_desc);
+ CTFontRef new_ct_font = CTFontCreateCopyWithAttributes (ct_font, 0.0, nullptr, last_resort_font_desc);
CFRelease (last_resort_font_desc);
if (new_ct_font)
{
@@ -221,51 +264,30 @@ create_ct_font (CGFontRef cg_font, CGFloat font_size)
return ct_font;
}
-struct hb_coretext_shaper_face_data_t {
- CGFontRef cg_font;
- CTFontRef ct_font;
-};
-
hb_coretext_shaper_face_data_t *
_hb_coretext_shaper_face_data_create (hb_face_t *face)
{
- hb_coretext_shaper_face_data_t *data = (hb_coretext_shaper_face_data_t *) calloc (1, sizeof (hb_coretext_shaper_face_data_t));
- if (unlikely (!data))
- return NULL;
+ CGFontRef cg_font = create_cg_font (face);
- data->cg_font = create_cg_font (face);
- if (unlikely (!data->cg_font))
+ if (unlikely (!cg_font))
{
DEBUG_MSG (CORETEXT, face, "CGFont creation failed..");
- free (data);
- return NULL;
+ return nullptr;
}
- /* We use 36pt size instead of UPEM, because CoreText implements the 'trak' table,
- * which can make the font too tight at large sizes. 36pt should be a good semi-neutral
- * size.
- *
- * Since we always create CTFont at a fixed size, our CTFont lives in face_data
- * instead of font_data. Which is good, because when people change scale on
- * hb_font_t, we won't need to update our CTFont. */
- data->ct_font = create_ct_font (data->cg_font, 36.);
- if (unlikely (!data->ct_font))
- {
- DEBUG_MSG (CORETEXT, face, "CTFont creation failed.");
- CFRelease (data->cg_font);
- free (data);
- return NULL;
- }
-
- return data;
+ return (hb_coretext_shaper_face_data_t *) cg_font;
}
void
_hb_coretext_shaper_face_data_destroy (hb_coretext_shaper_face_data_t *data)
{
- CFRelease (data->ct_font);
- CFRelease (data->cg_font);
- free (data);
+ CFRelease ((CGFontRef) data);
+}
+
+hb_face_t *
+hb_coretext_face_create (CGFontRef cg_font)
+{
+ return hb_face_create_for_tables (reference_table, CGFontRetain (cg_font), _hb_cg_font_release);
}
/*
@@ -274,29 +296,66 @@ _hb_coretext_shaper_face_data_destroy (hb_coretext_shaper_face_data_t *data)
CGFontRef
hb_coretext_face_get_cg_font (hb_face_t *face)
{
- if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return NULL;
- hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
- return face_data->cg_font;
+ if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return nullptr;
+ return (CGFontRef) HB_SHAPER_DATA_GET (face);
}
-/*
- * shaper font data
- */
-
-struct hb_coretext_shaper_font_data_t {};
-
hb_coretext_shaper_font_data_t *
-_hb_coretext_shaper_font_data_create (hb_font_t *font HB_UNUSED)
+_hb_coretext_shaper_font_data_create (hb_font_t *font)
{
- return (hb_coretext_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+ hb_face_t *face = font->face;
+ if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return nullptr;
+ CGFontRef cg_font = (CGFontRef) HB_SHAPER_DATA_GET (face);
+
+ CTFontRef ct_font = create_ct_font (cg_font, coretext_font_size_from_ptem (font->ptem));
+
+ if (unlikely (!ct_font))
+ {
+ DEBUG_MSG (CORETEXT, font, "CGFont creation failed..");
+ return nullptr;
+ }
+
+ return (hb_coretext_shaper_font_data_t *) ct_font;
}
void
_hb_coretext_shaper_font_data_destroy (hb_coretext_shaper_font_data_t *data)
{
+ CFRelease ((CTFontRef) data);
}
+/*
+ * Since: 1.7.2
+ */
+hb_font_t *
+hb_coretext_font_create (CTFontRef ct_font)
+{
+ CGFontRef cg_font = CTFontCopyGraphicsFont (ct_font, 0);
+ hb_face_t *face = hb_coretext_face_create (cg_font);
+ CFRelease (cg_font);
+ hb_font_t *font = hb_font_create (face);
+ hb_face_destroy (face);
+
+ if (unlikely (hb_object_is_inert (font)))
+ return font;
+
+ hb_font_set_ptem (font, coretext_font_size_to_ptem (CTFontGetSize(ct_font)));
+
+ /* Let there be dragons here... */
+ HB_SHAPER_DATA_GET (font) = (hb_coretext_shaper_font_data_t *) CFRetain (ct_font);
+
+ return font;
+}
+
+CTFontRef
+hb_coretext_font_get_ct_font (hb_font_t *font)
+{
+ if (unlikely (!hb_coretext_shaper_font_data_ensure (font))) return nullptr;
+ return (CTFontRef) HB_SHAPER_DATA_GET (font);
+}
+
+
/*
* shaper shape_plan data
@@ -319,15 +378,6 @@ _hb_coretext_shaper_shape_plan_data_destroy (hb_coretext_shaper_shape_plan_data_
{
}
-CTFontRef
-hb_coretext_font_get_ct_font (hb_font_t *font)
-{
- hb_face_t *face = font->face;
- if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return NULL;
- hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
- return face_data->ct_font;
-}
-
/*
* shaper
@@ -342,7 +392,9 @@ struct active_feature_t {
feature_record_t rec;
unsigned int order;
- static int cmp (const active_feature_t *a, const active_feature_t *b) {
+ static int cmp (const void *pa, const void *pb) {
+ const active_feature_t *a = (const active_feature_t *) pa;
+ const active_feature_t *b = (const active_feature_t *) pb;
return a->rec.feature < b->rec.feature ? -1 : a->rec.feature > b->rec.feature ? 1 :
a->order < b->order ? -1 : a->order > b->order ? 1 :
a->rec.setting < b->rec.setting ? -1 : a->rec.setting > b->rec.setting ? 1 :
@@ -358,7 +410,9 @@ struct feature_event_t {
bool start;
active_feature_t feature;
- static int cmp (const feature_event_t *a, const feature_event_t *b) {
+ static int cmp (const void *pa, const void *pb) {
+ const feature_event_t *a = (const feature_event_t *) pa;
+ const feature_event_t *b = (const feature_event_t *) pb;
return a->index < b->index ? -1 : a->index > b->index ? 1 :
a->start < b->start ? -1 : a->start > b->start ? 1 :
active_feature_t::cmp (&a->feature, &b->feature);
@@ -557,9 +611,10 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
unsigned int num_features)
{
hb_face_t *face = font->face;
- hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
+ CGFontRef cg_font = (CGFontRef) HB_SHAPER_DATA_GET (face);
+ CTFontRef ct_font = (CTFontRef) HB_SHAPER_DATA_GET (font);
- CGFloat ct_font_size = CTFontGetSize (face_data->ct_font);
+ CGFloat ct_font_size = CTFontGetSize (ct_font);
CGFloat x_mult = (CGFloat) font->x_scale / ct_font_size;
CGFloat y_mult = (CGFloat) font->y_scale / ct_font_size;
@@ -660,22 +715,23 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
/* active_features.qsort (); */
for (unsigned int j = 0; j < active_features.len; j++)
{
- CFStringRef keys[2] = {
+ CFStringRef keys[] = {
kCTFontFeatureTypeIdentifierKey,
kCTFontFeatureSelectorIdentifierKey
};
- CFNumberRef values[2] = {
+ CFNumberRef values[] = {
CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &active_features[j].rec.feature),
CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &active_features[j].rec.setting)
};
+ static_assert ((ARRAY_LENGTH_CONST (keys) == ARRAY_LENGTH_CONST (values)), "");
CFDictionaryRef dict = CFDictionaryCreate (kCFAllocatorDefault,
(const void **) keys,
(const void **) values,
- 2,
+ ARRAY_LENGTH (keys),
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
- CFRelease (values[0]);
- CFRelease (values[1]);
+ for (unsigned int i = 0; i < ARRAY_LENGTH (values); i++)
+ CFRelease (values[i]);
CFArrayAppendValue (features_array, dict);
CFRelease (dict);
@@ -693,12 +749,12 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
CTFontDescriptorRef font_desc = CTFontDescriptorCreateWithAttributes (attributes);
CFRelease (attributes);
- range->font = CTFontCreateCopyWithAttributes (face_data->ct_font, 0.0, NULL, font_desc);
+ range->font = CTFontCreateCopyWithAttributes (ct_font, 0.0, nullptr, font_desc);
CFRelease (font_desc);
}
else
{
- range->font = NULL;
+ range->font = nullptr;
}
range->index_first = last_index;
@@ -718,9 +774,6 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
active_features.remove (feature - active_features.array);
}
}
-
- if (!range_records.len) /* No active feature found. */
- goto fail_features;
}
else
{
@@ -771,14 +824,14 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
#define FAIL(...) \
HB_STMT_START { \
- DEBUG_MSG (CORETEXT, NULL, __VA_ARGS__); \
+ DEBUG_MSG (CORETEXT, nullptr, __VA_ARGS__); \
ret = false; \
goto fail; \
} HB_STMT_END;
bool ret = true;
- CFStringRef string_ref = NULL;
- CTLineRef line = NULL;
+ CFStringRef string_ref = nullptr;
+ CTLineRef line = nullptr;
if (0)
{
@@ -790,8 +843,8 @@ resize_and_retry:
assert (line);
CFRelease (string_ref);
CFRelease (line);
- string_ref = NULL;
- line = NULL;
+ string_ref = nullptr;
+ line = nullptr;
/* Get previous start-of-scratch-area, that we use later for readjusting
* our existing scratch arrays. */
@@ -812,7 +865,7 @@ resize_and_retry:
scratch_size -= old_scratch_used;
}
{
- string_ref = CFStringCreateWithCharactersNoCopy (NULL,
+ string_ref = CFStringCreateWithCharactersNoCopy (nullptr,
pchars, chars_len,
kCFAllocatorNull);
if (unlikely (!string_ref))
@@ -850,9 +903,9 @@ resize_and_retry:
CFRelease (lang);
}
CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len),
- kCTFontAttributeName, face_data->ct_font);
+ kCTFontAttributeName, ct_font);
- if (num_features)
+ if (num_features && range_records.len)
{
unsigned int start = 0;
range_record_t *last_range = &range_records[0];
@@ -878,6 +931,30 @@ resize_and_retry:
CFAttributedStringSetAttribute (attr_string, CFRangeMake (start, chars_len - start),
kCTFontAttributeName, last_range->font);
}
+ /* Enable/disable kern if requested.
+ *
+ * Note: once kern is disabled, reenabling it doesn't currently seem to work in CoreText.
+ */
+ if (num_features)
+ {
+ unsigned int zeroint = 0;
+ CFNumberRef zero = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &zeroint);
+ for (unsigned int i = 0; i < num_features; i++)
+ {
+ const hb_feature_t &feature = features[i];
+ if (feature.tag == HB_TAG('k','e','r','n') &&
+ feature.start < chars_len && feature.start < feature.end)
+ {
+ CFRange feature_range = CFRangeMake (feature.start,
+ MIN (feature.end, chars_len) - feature.start);
+ if (feature.value)
+ CFAttributedStringRemoveAttribute (attr_string, feature_range, kCTKernAttributeName);
+ else
+ CFAttributedStringSetAttribute (attr_string, feature_range, kCTKernAttributeName, zero);
+ }
+ }
+ CFRelease (zero);
+ }
int level = HB_DIRECTION_IS_FORWARD (buffer->props.direction) ? 0 : 1;
CFNumberRef level_number = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &level);
@@ -887,6 +964,7 @@ resize_and_retry:
1,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
+ CFRelease (level_number);
if (unlikely (!options))
FAIL ("CFDictionaryCreate failed");
@@ -904,7 +982,7 @@ resize_and_retry:
CFArrayRef glyph_runs = CTLineGetGlyphRuns (line);
unsigned int num_runs = CFArrayGetCount (glyph_runs);
- DEBUG_MSG (CORETEXT, NULL, "Num runs: %d", num_runs);
+ DEBUG_MSG (CORETEXT, nullptr, "Num runs: %d", num_runs);
buffer->len = 0;
uint32_t status_and = ~0, status_or = 0;
@@ -930,7 +1008,7 @@ resize_and_retry:
status_or |= run_status;
status_and &= run_status;
DEBUG_MSG (CORETEXT, run, "CTRunStatus: %x", run_status);
- double run_advance = CTRunGetTypographicBounds (run, range_all, NULL, NULL, NULL);
+ double run_advance = CTRunGetTypographicBounds (run, range_all, nullptr, nullptr, nullptr);
if (HB_DIRECTION_IS_VERTICAL (buffer->props.direction))
run_advance = -run_advance;
DEBUG_MSG (CORETEXT, run, "Run advance: %g", run_advance);
@@ -943,7 +1021,7 @@ resize_and_retry:
*/
CFDictionaryRef attributes = CTRunGetAttributes (run);
CTFontRef run_ct_font = static_cast<CTFontRef>(CFDictionaryGetValue (attributes, kCTFontAttributeName));
- if (!CFEqual (run_ct_font, face_data->ct_font))
+ if (!CFEqual (run_ct_font, ct_font))
{
/* The run doesn't use our main font instance. We have to figure out
* whether font fallback happened, or this is just CoreText giving us
@@ -965,7 +1043,7 @@ resize_and_retry:
* However, even that wouldn't work if we were passed in the CGFont to
* construct a hb_face to begin with.
*
- * See: http://github.com/behdad/harfbuzz/pull/36
+ * See: http://github.com/harfbuzz/harfbuzz/pull/36
*
* Also see: https://bugs.chromium.org/p/chromium/issues/detail?id=597098
*/
@@ -981,13 +1059,13 @@ resize_and_retry:
CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, 0);
if (run_cg_font)
{
- matched = CFEqual (run_cg_font, face_data->cg_font);
+ matched = CFEqual (run_cg_font, cg_font);
CFRelease (run_cg_font);
}
}
if (!matched)
{
- CFStringRef font_ps_name = CTFontCopyName (face_data->ct_font, kCTFontPostScriptNameKey);
+ CFStringRef font_ps_name = CTFontCopyName (ct_font, kCTFontPostScriptNameKey);
CFStringRef run_ps_name = CTFontCopyName (run_ct_font, kCTFontPostScriptNameKey);
CFComparisonResult result = CFStringCompare (run_ps_name, font_ps_name, 0);
CFRelease (run_ps_name);
@@ -1056,7 +1134,7 @@ resize_and_retry:
/* Testing used to indicate that CTRunGetGlyphsPtr, etc (almost?) always
* succeed, and so copying data to our own buffer will be rare. Reports
- * have it that this changed in OS X 10.10 Yosemite, and NULL is returned
+ * have it that this changed in OS X 10.10 Yosemite, and nullptr is returned
* frequently. At any rate, we can test that codepath by setting USE_PTR
* to false. */
@@ -1072,13 +1150,13 @@ resize_and_retry:
{ /* Setup glyphs */
SCRATCH_SAVE();
- const CGGlyph* glyphs = USE_PTR ? CTRunGetGlyphsPtr (run) : NULL;
+ const CGGlyph* glyphs = USE_PTR ? CTRunGetGlyphsPtr (run) : nullptr;
if (!glyphs) {
ALLOCATE_ARRAY (CGGlyph, glyph_buf, num_glyphs, goto resize_and_retry);
CTRunGetGlyphs (run, range_all, glyph_buf);
glyphs = glyph_buf;
}
- const CFIndex* string_indices = USE_PTR ? CTRunGetStringIndicesPtr (run) : NULL;
+ const CFIndex* string_indices = USE_PTR ? CTRunGetStringIndicesPtr (run) : nullptr;
if (!string_indices) {
ALLOCATE_ARRAY (CFIndex, index_buf, num_glyphs, goto resize_and_retry);
CTRunGetStringIndices (run, range_all, index_buf);
@@ -1100,7 +1178,7 @@ resize_and_retry:
* advance (in the advance direction only), and for last glyph we set
* whatever is needed to make the whole run's advance add up. */
SCRATCH_SAVE();
- const CGPoint* positions = USE_PTR ? CTRunGetPositionsPtr (run) : NULL;
+ const CGPoint* positions = USE_PTR ? CTRunGetPositionsPtr (run) : nullptr;
if (!positions) {
ALLOCATE_ARRAY (CGPoint, position_buf, num_glyphs, goto resize_and_retry);
CTRunGetPositions (run, range_all, position_buf);
@@ -1176,6 +1254,9 @@ resize_and_retry:
pos->x_advance = info->mask;
pos->x_offset = info->var1.i32;
pos->y_offset = info->var2.i32;
+
+ info->mask = HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
+
info++, pos++;
}
else
@@ -1184,6 +1265,9 @@ resize_and_retry:
pos->y_advance = info->mask;
pos->x_offset = info->var1.i32;
pos->y_offset = info->var2.i32;
+
+ info->mask = HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
+
info++, pos++;
}
@@ -1221,6 +1305,8 @@ resize_and_retry:
}
}
+ buffer->unsafe_to_break_all ();
+
#undef FAIL
fail:
@@ -1241,6 +1327,9 @@ fail:
* AAT shaper
*/
+HB_SHAPER_DATA_ENSURE_DEFINE(coretext_aat, face)
+HB_SHAPER_DATA_ENSURE_DEFINE(coretext_aat, font)
+
/*
* shaper face data
*/
@@ -1250,22 +1339,20 @@ struct hb_coretext_aat_shaper_face_data_t {};
hb_coretext_aat_shaper_face_data_t *
_hb_coretext_aat_shaper_face_data_create (hb_face_t *face)
{
- hb_blob_t *mort_blob = face->reference_table (HB_CORETEXT_TAG_MORT);
- /* Umm, we just reference the table to check whether it exists.
- * Maybe add better API for this? */
- if (!hb_blob_get_length (mort_blob))
+ static const hb_tag_t tags[] = {HB_CORETEXT_TAG_MORX, HB_CORETEXT_TAG_MORT, HB_CORETEXT_TAG_KERX};
+
+ for (unsigned int i = 0; i < ARRAY_LENGTH (tags); i++)
{
- hb_blob_destroy (mort_blob);
- mort_blob = face->reference_table (HB_CORETEXT_TAG_MORX);
- if (!hb_blob_get_length (mort_blob))
+ hb_blob_t *blob = face->reference_table (tags[i]);
+ if (hb_blob_get_length (blob))
{
- hb_blob_destroy (mort_blob);
- return NULL;
+ hb_blob_destroy (blob);
+ return hb_coretext_shaper_face_data_ensure (face) ? (hb_coretext_aat_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr;
}
+ hb_blob_destroy (blob);
}
- hb_blob_destroy (mort_blob);
- return hb_coretext_shaper_face_data_ensure (face) ? (hb_coretext_aat_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED : NULL;
+ return nullptr;
}
void
@@ -1283,7 +1370,7 @@ struct hb_coretext_aat_shaper_font_data_t {};
hb_coretext_aat_shaper_font_data_t *
_hb_coretext_aat_shaper_font_data_create (hb_font_t *font)
{
- return hb_coretext_shaper_font_data_ensure (font) ? (hb_coretext_aat_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED : NULL;
+ return hb_coretext_shaper_font_data_ensure (font) ? (hb_coretext_aat_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr;
}
void
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-coretext.h b/src/3rdparty/harfbuzz-ng/src/hb-coretext.h
index 82066e4e0d..4b0a6f01b6 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-coretext.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-coretext.h
@@ -42,11 +42,15 @@ HB_BEGIN_DECLS
#define HB_CORETEXT_TAG_MORT HB_TAG('m','o','r','t')
#define HB_CORETEXT_TAG_MORX HB_TAG('m','o','r','x')
+#define HB_CORETEXT_TAG_KERX HB_TAG('k','e','r','x')
HB_EXTERN hb_face_t *
hb_coretext_face_create (CGFontRef cg_font);
+HB_EXTERN hb_font_t *
+hb_coretext_font_create (CTFontRef ct_font);
+
HB_EXTERN CGFontRef
hb_coretext_face_get_cg_font (hb_face_t *face);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-debug.hh b/src/3rdparty/harfbuzz-ng/src/hb-debug.hh
new file mode 100644
index 0000000000..6c425f7b9d
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-debug.hh
@@ -0,0 +1,431 @@
+/*
+ * 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_DEBUG_HH
+#define HB_DEBUG_HH
+
+#include "hb-private.hh"
+
+
+#ifndef HB_DEBUG
+#define HB_DEBUG 0
+#endif
+
+static inline bool
+_hb_debug (unsigned int level,
+ unsigned int max_level)
+{
+ return level < max_level;
+}
+
+#define DEBUG_LEVEL_ENABLED(WHAT, LEVEL) (_hb_debug ((LEVEL), HB_DEBUG_##WHAT))
+#define DEBUG_ENABLED(WHAT) (DEBUG_LEVEL_ENABLED (WHAT, 0))
+
+static inline void
+_hb_print_func (const char *func)
+{
+ if (func)
+ {
+ unsigned int func_len = strlen (func);
+ /* Skip "static" */
+ if (0 == strncmp (func, "static ", 7))
+ func += 7;
+ /* Skip "typename" */
+ if (0 == strncmp (func, "typename ", 9))
+ func += 9;
+ /* Skip return type */
+ const char *space = strchr (func, ' ');
+ if (space)
+ func = space + 1;
+ /* Skip parameter list */
+ const char *paren = strchr (func, '(');
+ if (paren)
+ func_len = paren - func;
+ fprintf (stderr, "%.*s", func_len, func);
+ }
+}
+
+template <int max_level> static inline void
+_hb_debug_msg_va (const char *what,
+ const void *obj,
+ const char *func,
+ bool indented,
+ unsigned int level,
+ int level_dir,
+ const char *message,
+ va_list ap) HB_PRINTF_FUNC(7, 0);
+template <int max_level> static inline void
+_hb_debug_msg_va (const char *what,
+ const void *obj,
+ const char *func,
+ bool indented,
+ unsigned int level,
+ int level_dir,
+ const char *message,
+ va_list ap)
+{
+ if (!_hb_debug (level, max_level))
+ return;
+
+ fprintf (stderr, "%-10s", what ? what : "");
+
+ if (obj)
+ fprintf (stderr, "(%*p) ", (unsigned int) (2 * sizeof (void *)), obj);
+ else
+ fprintf (stderr, " %*s ", (unsigned int) (2 * sizeof (void *)), "");
+
+ if (indented) {
+#define VBAR "\342\224\202" /* U+2502 BOX DRAWINGS LIGHT VERTICAL */
+#define VRBAR "\342\224\234" /* U+251C BOX DRAWINGS LIGHT VERTICAL AND RIGHT */
+#define DLBAR "\342\225\256" /* U+256E BOX DRAWINGS LIGHT ARC DOWN AND LEFT */
+#define ULBAR "\342\225\257" /* U+256F BOX DRAWINGS LIGHT ARC UP AND LEFT */
+#define LBAR "\342\225\264" /* U+2574 BOX DRAWINGS LIGHT LEFT */
+ static const char bars[] =
+ VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR
+ VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR
+ VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR
+ VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR
+ VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR;
+ fprintf (stderr, "%2u %s" VRBAR "%s",
+ level,
+ bars + sizeof (bars) - 1 - MIN ((unsigned int) sizeof (bars) - 1, (unsigned int) (sizeof (VBAR) - 1) * level),
+ level_dir ? (level_dir > 0 ? DLBAR : ULBAR) : LBAR);
+ } else
+ fprintf (stderr, " " VRBAR LBAR);
+
+ _hb_print_func (func);
+
+ if (message)
+ {
+ fprintf (stderr, ": ");
+ vfprintf (stderr, message, ap);
+ }
+
+ fprintf (stderr, "\n");
+}
+template <> inline void
+_hb_debug_msg_va<0> (const char *what HB_UNUSED,
+ const void *obj HB_UNUSED,
+ const char *func HB_UNUSED,
+ bool indented HB_UNUSED,
+ unsigned int level HB_UNUSED,
+ int level_dir HB_UNUSED,
+ const char *message HB_UNUSED,
+ va_list ap HB_UNUSED) {}
+
+template <int max_level> static inline void
+_hb_debug_msg (const char *what,
+ const void *obj,
+ const char *func,
+ bool indented,
+ unsigned int level,
+ int level_dir,
+ const char *message,
+ ...) HB_PRINTF_FUNC(7, 8);
+template <int max_level> static inline void
+_hb_debug_msg (const char *what,
+ const void *obj,
+ const char *func,
+ bool indented,
+ unsigned int level,
+ int level_dir,
+ const char *message,
+ ...)
+{
+ va_list ap;
+ va_start (ap, message);
+ _hb_debug_msg_va<max_level> (what, obj, func, indented, level, level_dir, message, ap);
+ va_end (ap);
+}
+template <> inline void
+_hb_debug_msg<0> (const char *what HB_UNUSED,
+ const void *obj HB_UNUSED,
+ const char *func HB_UNUSED,
+ bool indented HB_UNUSED,
+ unsigned int level HB_UNUSED,
+ int level_dir HB_UNUSED,
+ const char *message HB_UNUSED,
+ ...) HB_PRINTF_FUNC(7, 8);
+template <> inline void
+_hb_debug_msg<0> (const char *what HB_UNUSED,
+ const void *obj HB_UNUSED,
+ const char *func HB_UNUSED,
+ bool indented HB_UNUSED,
+ unsigned int level HB_UNUSED,
+ int level_dir HB_UNUSED,
+ const char *message HB_UNUSED,
+ ...) {}
+
+#define DEBUG_MSG_LEVEL(WHAT, OBJ, LEVEL, LEVEL_DIR, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), nullptr, true, (LEVEL), (LEVEL_DIR), __VA_ARGS__)
+#define DEBUG_MSG(WHAT, OBJ, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), nullptr, false, 0, 0, __VA_ARGS__)
+#define DEBUG_MSG_FUNC(WHAT, OBJ, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), HB_FUNC, false, 0, 0, __VA_ARGS__)
+
+
+/*
+ * Printer
+ */
+
+template <typename T>
+struct hb_printer_t {
+ const char *print (const T&) { return "something"; }
+};
+
+template <>
+struct hb_printer_t<bool> {
+ const char *print (bool v) { return v ? "true" : "false"; }
+};
+
+template <>
+struct hb_printer_t<hb_void_t> {
+ const char *print (hb_void_t) { return ""; }
+};
+
+
+/*
+ * Trace
+ */
+
+template <typename T>
+static inline void _hb_warn_no_return (bool returned)
+{
+ if (unlikely (!returned)) {
+ fprintf (stderr, "OUCH, returned with no call to return_trace(). This is a bug, please report.\n");
+ }
+}
+template <>
+/*static*/ inline void _hb_warn_no_return<hb_void_t> (bool returned HB_UNUSED)
+{}
+
+template <int max_level, typename ret_t>
+struct hb_auto_trace_t
+{
+ explicit inline hb_auto_trace_t (unsigned int *plevel_,
+ const char *what_,
+ const void *obj_,
+ const char *func,
+ const char *message,
+ ...) HB_PRINTF_FUNC(6, 7)
+ : plevel (plevel_), what (what_), obj (obj_), returned (false)
+ {
+ if (plevel) ++*plevel;
+
+ va_list ap;
+ va_start (ap, message);
+ _hb_debug_msg_va<max_level> (what, obj, func, true, plevel ? *plevel : 0, +1, message, ap);
+ va_end (ap);
+ }
+ inline ~hb_auto_trace_t (void)
+ {
+ _hb_warn_no_return<ret_t> (returned);
+ if (!returned) {
+ _hb_debug_msg<max_level> (what, obj, nullptr, true, plevel ? *plevel : 1, -1, " ");
+ }
+ if (plevel) --*plevel;
+ }
+
+ inline ret_t ret (ret_t v, unsigned int line = 0)
+ {
+ if (unlikely (returned)) {
+ fprintf (stderr, "OUCH, double calls to return_trace(). This is a bug, please report.\n");
+ return v;
+ }
+
+ _hb_debug_msg<max_level> (what, obj, nullptr, true, plevel ? *plevel : 1, -1,
+ "return %s (line %d)",
+ hb_printer_t<ret_t>().print (v), line);
+ if (plevel) --*plevel;
+ plevel = nullptr;
+ returned = true;
+ return v;
+ }
+
+ private:
+ unsigned int *plevel;
+ const char *what;
+ const void *obj;
+ bool returned;
+};
+template <typename ret_t> /* Make sure we don't use hb_auto_trace_t when not tracing. */
+struct hb_auto_trace_t<0, ret_t>
+{
+ explicit inline hb_auto_trace_t (unsigned int *plevel_,
+ const char *what_,
+ const void *obj_,
+ const char *func,
+ const char *message,
+ ...) HB_PRINTF_FUNC(6, 7) {}
+
+ inline ret_t ret (ret_t v, unsigned int line HB_UNUSED = 0) { return v; }
+};
+
+/* For disabled tracing; optimize out everything.
+ * https://github.com/harfbuzz/harfbuzz/pull/605 */
+template <typename ret_t>
+struct hb_no_trace_t {
+ inline ret_t ret (ret_t v, unsigned int line HB_UNUSED = 0) { return v; }
+};
+
+#define return_trace(RET) return trace.ret (RET, __LINE__)
+
+
+/*
+ * Instances.
+ */
+
+#ifndef HB_DEBUG_ARABIC
+#define HB_DEBUG_ARABIC (HB_DEBUG+0)
+#endif
+
+#ifndef HB_DEBUG_BLOB
+#define HB_DEBUG_BLOB (HB_DEBUG+0)
+#endif
+
+#ifndef HB_DEBUG_CORETEXT
+#define HB_DEBUG_CORETEXT (HB_DEBUG+0)
+#endif
+
+#ifndef HB_DEBUG_DIRECTWRITE
+#define HB_DEBUG_DIRECTWRITE (HB_DEBUG+0)
+#endif
+
+#ifndef HB_DEBUG_FT
+#define HB_DEBUG_FT (HB_DEBUG+0)
+#endif
+
+#ifndef HB_DEBUG_GET_COVERAGE
+#define HB_DEBUG_GET_COVERAGE (HB_DEBUG+0)
+#endif
+
+#ifndef HB_DEBUG_OBJECT
+#define HB_DEBUG_OBJECT (HB_DEBUG+0)
+#endif
+
+#ifndef HB_DEBUG_SHAPE_PLAN
+#define HB_DEBUG_SHAPE_PLAN (HB_DEBUG+0)
+#endif
+
+#ifndef HB_DEBUG_UNISCRIBE
+#define HB_DEBUG_UNISCRIBE (HB_DEBUG+0)
+#endif
+
+/*
+ * With tracing.
+ */
+
+#ifndef HB_DEBUG_APPLY
+#define HB_DEBUG_APPLY (HB_DEBUG+0)
+#endif
+#if HB_DEBUG_APPLY
+#define TRACE_APPLY(this) \
+ hb_auto_trace_t<HB_DEBUG_APPLY, bool> trace \
+ (&c->debug_depth, c->get_name (), this, HB_FUNC, \
+ "idx %d gid %u lookup %d", \
+ c->buffer->idx, c->buffer->cur().codepoint, (int) c->lookup_index)
+#else
+#define TRACE_APPLY(this) hb_no_trace_t<bool> trace
+#endif
+
+#ifndef HB_DEBUG_CLOSURE
+#define HB_DEBUG_CLOSURE (HB_DEBUG+0)
+#endif
+#if HB_DEBUG_CLOSURE
+#define TRACE_CLOSURE(this) \
+ hb_auto_trace_t<HB_DEBUG_CLOSURE, hb_void_t> trace \
+ (&c->debug_depth, c->get_name (), this, HB_FUNC, \
+ " ")
+#else
+#define TRACE_CLOSURE(this) hb_no_trace_t<hb_void_t> trace HB_UNUSED
+#endif
+
+#ifndef HB_DEBUG_COLLECT_GLYPHS
+#define HB_DEBUG_COLLECT_GLYPHS (HB_DEBUG+0)
+#endif
+#if HB_DEBUG_COLLECT_GLYPHS
+#define TRACE_COLLECT_GLYPHS(this) \
+ hb_auto_trace_t<HB_DEBUG_COLLECT_GLYPHS, hb_void_t> trace \
+ (&c->debug_depth, c->get_name (), this, HB_FUNC, \
+ " ")
+#else
+#define TRACE_COLLECT_GLYPHS(this) hb_no_trace_t<hb_void_t> trace HB_UNUSED
+#endif
+
+#ifndef HB_DEBUG_SANITIZE
+#define HB_DEBUG_SANITIZE (HB_DEBUG+0)
+#endif
+#if HB_DEBUG_SANITIZE
+#define TRACE_SANITIZE(this) \
+ hb_auto_trace_t<HB_DEBUG_SANITIZE, bool> trace \
+ (&c->debug_depth, c->get_name (), this, HB_FUNC, \
+ " ");
+#else
+#define TRACE_SANITIZE(this) hb_no_trace_t<bool> trace
+#endif
+
+#ifndef HB_DEBUG_SERIALIZE
+#define HB_DEBUG_SERIALIZE (HB_DEBUG+0)
+#endif
+#if HB_DEBUG_SERIALIZE
+#define TRACE_SERIALIZE(this) \
+ hb_auto_trace_t<HB_DEBUG_SERIALIZE, bool> trace \
+ (&c->debug_depth, "SERIALIZE", c, HB_FUNC, \
+ " ");
+#else
+#define TRACE_SERIALIZE(this) hb_no_trace_t<bool> trace
+#endif
+
+#ifndef HB_DEBUG_WOULD_APPLY
+#define HB_DEBUG_WOULD_APPLY (HB_DEBUG+0)
+#endif
+#if HB_DEBUG_WOULD_APPLY
+#define TRACE_WOULD_APPLY(this) \
+ hb_auto_trace_t<HB_DEBUG_WOULD_APPLY, bool> trace \
+ (&c->debug_depth, c->get_name (), this, HB_FUNC, \
+ "%d glyphs", c->len);
+#else
+#define TRACE_WOULD_APPLY(this) hb_no_trace_t<bool> trace
+#endif
+
+#ifndef HB_DEBUG_DISPATCH
+#define HB_DEBUG_DISPATCH ( \
+ HB_DEBUG_APPLY + \
+ HB_DEBUG_CLOSURE + \
+ HB_DEBUG_COLLECT_GLYPHS + \
+ HB_DEBUG_SANITIZE + \
+ HB_DEBUG_SERIALIZE + \
+ HB_DEBUG_WOULD_APPLY + \
+ 0)
+#endif
+#if HB_DEBUG_DISPATCH
+#define TRACE_DISPATCH(this, format) \
+ hb_auto_trace_t<context_t::max_debug_depth, typename context_t::return_t> trace \
+ (&c->debug_depth, c->get_name (), this, HB_FUNC, \
+ "format %d", (int) format);
+#else
+#define TRACE_DISPATCH(this, format) hb_no_trace_t<typename context_t::return_t> trace
+#endif
+
+
+#endif /* HB_DEBUG_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-deprecated.h b/src/3rdparty/harfbuzz-ng/src/hb-deprecated.h
index 0398dfae60..eac7efb42f 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-deprecated.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-deprecated.h
@@ -34,6 +34,7 @@
#include "hb-common.h"
#include "hb-unicode.h"
#include "hb-font.h"
+#include "hb-set.h"
HB_BEGIN_DECLS
@@ -54,6 +55,9 @@ hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_func_t func,
void *user_data, hb_destroy_func_t destroy);
+HB_EXTERN void
+hb_set_invert (hb_set_t *set);
+
#endif
HB_END_DECLS
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-dsalgs.hh b/src/3rdparty/harfbuzz-ng/src/hb-dsalgs.hh
new file mode 100644
index 0000000000..4e8f0431c6
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-dsalgs.hh
@@ -0,0 +1,167 @@
+/*
+ * 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_DSALGS_HH
+#define HB_DSALGS_HH
+
+#include "hb-private.hh"
+
+#if defined(__ghs)
+// GHS compiler doesn't support the __restrict keyword
+#define __restrict
+#endif
+
+
+
+static inline void *
+hb_bsearch_r (const void *key, const void *base,
+ size_t nmemb, size_t size,
+ int (*compar)(const void *_key, const void *_item, void *_arg),
+ void *arg)
+{
+ int min = 0, max = (int) nmemb - 1;
+ while (min <= max)
+ {
+ int mid = (min + max) / 2;
+ const void *p = (const void *) (((const char *) base) + (mid * size));
+ int c = compar (key, p, arg);
+ if (c < 0)
+ max = mid - 1;
+ else if (c > 0)
+ min = mid + 1;
+ else
+ return (void *) p;
+ }
+ return NULL;
+}
+
+
+
+/* From https://github.com/noporpoise/sort_r */
+
+/* Isaac Turner 29 April 2014 Public Domain */
+
+/*
+
+hb_sort_r function to be exported.
+
+Parameters:
+ base is the array to be sorted
+ nel is the number of elements in the array
+ width is the size in bytes of each element of the array
+ compar is the comparison function
+ arg is a pointer to be passed to the comparison function
+
+void hb_sort_r(void *base, size_t nel, size_t width,
+ int (*compar)(const void *_a, const void *_b, void *_arg),
+ void *arg);
+*/
+
+
+/* swap a, b iff a>b */
+/* __restrict is same as restrict but better support on old machines */
+static int sort_r_cmpswap(char *__restrict a, char *__restrict b, size_t w,
+ int (*compar)(const void *_a, const void *_b,
+ void *_arg),
+ void *arg)
+{
+ char tmp, *end = a+w;
+ if(compar(a, b, arg) > 0) {
+ for(; a < end; a++, b++) { tmp = *a; *a = *b; *b = tmp; }
+ return 1;
+ }
+ return 0;
+}
+
+/* Note: quicksort is not stable, equivalent values may be swapped */
+static inline void sort_r_simple(void *base, size_t nel, size_t w,
+ int (*compar)(const void *_a, const void *_b,
+ void *_arg),
+ void *arg)
+{
+ char *b = (char *)base, *end = b + nel*w;
+ if(nel < 7) {
+ /* Insertion sort for arbitrarily small inputs */
+ char *pi, *pj;
+ for(pi = b+w; pi < end; pi += w) {
+ for(pj = pi; pj > b && sort_r_cmpswap(pj-w,pj,w,compar,arg); pj -= w) {}
+ }
+ }
+ else
+ {
+ /* nel > 6; Quicksort */
+
+ /* Use median of first, middle and last items as pivot */
+ char *x, *y, *xend, ch;
+ char *pl, *pr;
+ char *last = b+w*(nel-1), *tmp;
+ char *l[3];
+ l[0] = b;
+ l[1] = b+w*(nel/2);
+ l[2] = last;
+
+ if(compar(l[0],l[1],arg) > 0) { tmp=l[0]; l[0]=l[1]; l[1]=tmp; }
+ if(compar(l[1],l[2],arg) > 0) {
+ tmp=l[1]; l[1]=l[2]; l[2]=tmp; /* swap(l[1],l[2]) */
+ if(compar(l[0],l[1],arg) > 0) { tmp=l[0]; l[0]=l[1]; l[1]=tmp; }
+ }
+
+ /* swap l[id], l[2] to put pivot as last element */
+ for(x = l[1], y = last, xend = x+w; x<xend; x++, y++) {
+ ch = *x; *x = *y; *y = ch;
+ }
+
+ pl = b;
+ pr = last;
+
+ while(pl < pr) {
+ for(; pl < pr; pl += w) {
+ if(sort_r_cmpswap(pl, pr, w, compar, arg)) {
+ pr -= w; /* pivot now at pl */
+ break;
+ }
+ }
+ for(; pl < pr; pr -= w) {
+ if(sort_r_cmpswap(pl, pr, w, compar, arg)) {
+ pl += w; /* pivot now at pr */
+ break;
+ }
+ }
+ }
+
+ sort_r_simple(b, (pl-b)/w, w, compar, arg);
+ sort_r_simple(pl+w, (end-(pl+w))/w, w, compar, arg);
+ }
+}
+
+static inline void hb_sort_r(void *base, size_t nel, size_t width,
+ int (*compar)(const void *_a, const void *_b, void *_arg),
+ void *arg)
+{
+ sort_r_simple(base, nel, width, compar, arg);
+}
+
+#endif /* HB_DSALGS_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-face-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-face-private.hh
index c4266fff4f..43e7b1cb3f 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-face-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-face-private.hh
@@ -50,12 +50,16 @@ struct hb_face_t {
void *user_data;
hb_destroy_func_t destroy;
- unsigned int index;
- mutable unsigned int upem;
- mutable unsigned int num_glyphs;
+ unsigned int index; /* Face index in a collection, zero-based. */
+ mutable unsigned int upem; /* Units-per-EM. */
+ mutable unsigned int num_glyphs; /* Number of glyphs. */
- struct hb_shaper_data_t shaper_data;
+ struct hb_shaper_data_t shaper_data; /* Various shaper data. */
+ /* Various non-shaping data. */
+ /* ... */
+
+ /* Cache */
struct plan_node_t {
hb_shape_plan_t *shape_plan;
plan_node_t *next;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-face.cc b/src/3rdparty/harfbuzz-ng/src/hb-face.cc
index 6b563bc8f1..26fddbe529 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-face.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-face.cc
@@ -28,15 +28,11 @@
#include "hb-private.hh"
-#include "hb-ot-layout-private.hh"
-
-#include "hb-font-private.hh"
+#include "hb-face-private.hh"
#include "hb-open-file-private.hh"
#include "hb-ot-head-table.hh"
#include "hb-ot-maxp-table.hh"
-#include <string.h>
-
/*
* hb_face_t
@@ -47,9 +43,9 @@ const hb_face_t _hb_face_nil = {
true, /* immutable */
- NULL, /* reference_table_func */
- NULL, /* user_data */
- NULL, /* destroy */
+ nullptr, /* reference_table_func */
+ nullptr, /* user_data */
+ nullptr, /* destroy */
0, /* index */
1000, /* upem */
@@ -61,7 +57,7 @@ const hb_face_t _hb_face_nil = {
#undef HB_SHAPER_IMPLEMENT
},
- NULL, /* shape_plans */
+ nullptr, /* shape_plans */
};
@@ -113,7 +109,7 @@ _hb_face_for_data_closure_create (hb_blob_t *blob, unsigned int index)
closure = (hb_face_for_data_closure_t *) calloc (1, sizeof (hb_face_for_data_closure_t));
if (unlikely (!closure))
- return NULL;
+ return nullptr;
closure->blob = blob;
closure->index = index;
@@ -122,8 +118,10 @@ _hb_face_for_data_closure_create (hb_blob_t *blob, unsigned int index)
}
static void
-_hb_face_for_data_closure_destroy (hb_face_for_data_closure_t *closure)
+_hb_face_for_data_closure_destroy (void *data)
{
+ hb_face_for_data_closure_t *closure = (hb_face_for_data_closure_t *) data;
+
hb_blob_destroy (closure->blob);
free (closure);
}
@@ -173,9 +171,9 @@ hb_face_create (hb_blob_t *blob,
face = hb_face_create_for_tables (_hb_face_for_data_reference_table,
closure,
- (hb_destroy_func_t) _hb_face_for_data_closure_destroy);
+ _hb_face_for_data_closure_destroy);
- hb_face_set_index (face, index);
+ face->index = index;
return face;
}
@@ -476,4 +474,33 @@ hb_face_t::load_num_glyphs (void) const
hb_blob_destroy (maxp_blob);
}
+/**
+ * hb_face_get_table_tags:
+ * @face: a face.
+ *
+ * Retrieves table tags for a face, if possible.
+ *
+ * Return value: total number of tables, or 0 if not possible to list.
+ *
+ * Since: 1.6.0
+ **/
+unsigned int
+hb_face_get_table_tags (hb_face_t *face,
+ unsigned int start_offset,
+ unsigned int *table_count, /* IN/OUT */
+ hb_tag_t *table_tags /* OUT */)
+{
+ if (face->destroy != _hb_face_for_data_closure_destroy)
+ {
+ if (table_count)
+ *table_count = 0;
+ return 0;
+ }
+
+ hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) face->user_data;
+ const OT::OpenTypeFontFile &ot_file = *OT::Sanitizer<OT::OpenTypeFontFile>::lock_instance (data->blob);
+ const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index);
+
+ return ot_face.get_table_tags (start_offset, table_count, table_tags);
+}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-face.h b/src/3rdparty/harfbuzz-ng/src/hb-face.h
index 91237b7085..9842d52b65 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-face.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-face.h
@@ -111,6 +111,11 @@ hb_face_set_glyph_count (hb_face_t *face,
HB_EXTERN unsigned int
hb_face_get_glyph_count (hb_face_t *face);
+HB_EXTERN unsigned int
+hb_face_get_table_tags (hb_face_t *face,
+ unsigned int start_offset,
+ unsigned int *table_count, /* IN/OUT */
+ hb_tag_t *table_tags /* OUT */);
HB_END_DECLS
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc
index ac6d4b00f5..3f09c3f530 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc
@@ -28,6 +28,10 @@
#include "hb-shaper-impl-private.hh"
+HB_SHAPER_DATA_ENSURE_DEFINE(fallback, face)
+HB_SHAPER_DATA_ENSURE_DEFINE(fallback, font)
+
+
/*
* shaper face data
*/
@@ -125,7 +129,7 @@ _hb_fallback_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
pos[i].y_advance = 0;
continue;
}
- font->get_nominal_glyph (info[i].codepoint, &info[i].codepoint);
+ (void) font->get_nominal_glyph (info[i].codepoint, &info[i].codepoint);
font->get_glyph_advance_for_direction (info[i].codepoint,
direction,
&pos[i].x_advance,
@@ -139,5 +143,7 @@ _hb_fallback_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
if (HB_DIRECTION_IS_BACKWARD (direction))
hb_buffer_reverse (buffer);
+ buffer->safe_to_break_all ();
+
return true;
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh
index 53671d78d2..d2801fb86e 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh
@@ -108,6 +108,8 @@ struct hb_font_t {
unsigned int x_ppem;
unsigned int y_ppem;
+ float ptem;
+
/* Font variation coordinates. */
unsigned int num_coords;
int *coords;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font.cc b/src/3rdparty/harfbuzz-ng/src/hb-font.cc
index 2935c4b4fd..f3534b686b 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-font.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-font.cc
@@ -28,14 +28,7 @@
#include "hb-private.hh"
-#include "hb-ot-layout-private.hh"
-
#include "hb-font-private.hh"
-#include "hb-open-file-private.hh"
-#include "hb-ot-head-table.hh"
-#include "hb-ot-maxp-table.hh"
-
-#include <string.h>
/*
@@ -43,7 +36,7 @@
*/
static hb_bool_t
-hb_font_get_font_h_extents_nil (hb_font_t *font,
+hb_font_get_font_h_extents_nil (hb_font_t *font HB_UNUSED,
void *font_data HB_UNUSED,
hb_font_extents_t *metrics,
void *user_data HB_UNUSED)
@@ -67,7 +60,7 @@ hb_font_get_font_h_extents_parent (hb_font_t *font,
}
static hb_bool_t
-hb_font_get_font_v_extents_nil (hb_font_t *font,
+hb_font_get_font_v_extents_nil (hb_font_t *font HB_UNUSED,
void *font_data HB_UNUSED,
hb_font_extents_t *metrics,
void *user_data HB_UNUSED)
@@ -354,12 +347,12 @@ static const hb_font_funcs_t _hb_font_funcs_nil = {
true, /* immutable */
{
-#define HB_FONT_FUNC_IMPLEMENT(name) NULL,
+#define HB_FONT_FUNC_IMPLEMENT(name) nullptr,
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT
},
{
-#define HB_FONT_FUNC_IMPLEMENT(name) NULL,
+#define HB_FONT_FUNC_IMPLEMENT(name) nullptr,
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT
},
@@ -377,12 +370,12 @@ static const hb_font_funcs_t _hb_font_funcs_parent = {
true, /* immutable */
{
-#define HB_FONT_FUNC_IMPLEMENT(name) NULL,
+#define HB_FONT_FUNC_IMPLEMENT(name) nullptr,
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT
},
{
-#define HB_FONT_FUNC_IMPLEMENT(name) NULL,
+#define HB_FONT_FUNC_IMPLEMENT(name) nullptr,
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT
},
@@ -570,8 +563,8 @@ hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \
ffuncs->destroy.name = destroy; \
} else { \
ffuncs->get.f.name = hb_font_get_##name##_parent; \
- ffuncs->user_data.name = NULL; \
- ffuncs->destroy.name = NULL; \
+ ffuncs->user_data.name = nullptr; \
+ ffuncs->destroy.name = nullptr; \
} \
}
@@ -1164,8 +1157,20 @@ hb_font_create_sub_font (hb_font_t *parent)
font->y_scale = parent->y_scale;
font->x_ppem = parent->x_ppem;
font->y_ppem = parent->y_ppem;
+ font->ptem = parent->ptem;
- /* TODO: copy variation coordinates. */
+ font->num_coords = parent->num_coords;
+ if (!font->num_coords)
+ font->coords = nullptr;
+ else
+ {
+ unsigned int size = parent->num_coords * sizeof (parent->coords[0]);
+ font->coords = (int *) malloc (size);
+ if (unlikely (!font->coords))
+ font->num_coords = 0;
+ else
+ memcpy (font->coords, parent->coords, size);
+ }
return font;
}
@@ -1187,7 +1192,7 @@ hb_font_get_empty (void)
true, /* immutable */
- NULL, /* parent */
+ nullptr, /* parent */
const_cast<hb_face_t *> (&_hb_face_nil),
1000, /* x_scale */
@@ -1195,13 +1200,14 @@ hb_font_get_empty (void)
0, /* x_ppem */
0, /* y_ppem */
+ 0, /* ptem */
0, /* num_coords */
- NULL, /* coords */
+ nullptr, /* coords */
const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil), /* klass */
- NULL, /* user_data */
- NULL, /* destroy */
+ nullptr, /* user_data */
+ nullptr, /* destroy */
{
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
@@ -1379,6 +1385,32 @@ hb_font_get_parent (hb_font_t *font)
}
/**
+ * hb_font_set_face:
+ * @font: a font.
+ * @face: new face.
+ *
+ * Sets font-face of @font.
+ *
+ * Since: 1.4.3
+ **/
+void
+hb_font_set_face (hb_font_t *font,
+ hb_face_t *face)
+{
+ if (font->immutable)
+ return;
+
+ if (unlikely (!face))
+ face = hb_face_get_empty ();
+
+ hb_face_t *old = font->face;
+
+ font->face = hb_face_reference (face);
+
+ hb_face_destroy (old);
+}
+
+/**
* hb_font_get_face:
* @font: a font.
*
@@ -1543,30 +1575,146 @@ hb_font_get_ppem (hb_font_t *font,
if (y_ppem) *y_ppem = font->y_ppem;
}
+/**
+ * hb_font_set_ptem:
+ * @font: a font.
+ * @ptem:
+ *
+ * Sets "point size" of the font.
+ *
+ * Since: 1.6.0
+ **/
+void
+hb_font_set_ptem (hb_font_t *font, float ptem)
+{
+ if (font->immutable)
+ return;
+
+ font->ptem = ptem;
+}
+
+/**
+ * hb_font_get_ptem:
+ * @font: a font.
+ *
+ * Gets the "point size" of the font. A value of 0 means unset.
+ *
+ * Return value: Point size.
+ *
+ * Since: 0.9.2
+ **/
+float
+hb_font_get_ptem (hb_font_t *font)
+{
+ return font->ptem;
+}
+/*
+ * Variations
+ */
+
+static void
+_hb_font_adopt_var_coords_normalized (hb_font_t *font,
+ int *coords, /* 2.14 normalized */
+ unsigned int coords_length)
+{
+ free (font->coords);
+
+ font->coords = coords;
+ font->num_coords = coords_length;
+}
+
+/**
+ * hb_font_set_variations:
+ *
+ * Since: 1.4.2
+ */
+void
+hb_font_set_variations (hb_font_t *font,
+ const hb_variation_t *variations,
+ unsigned int variations_length)
+{
+ if (font->immutable)
+ return;
+
+ if (!variations_length)
+ {
+ hb_font_set_var_coords_normalized (font, nullptr, 0);
+ return;
+ }
+
+ unsigned int coords_length = hb_ot_var_get_axis_count (font->face);
+
+ int *normalized = coords_length ? (int *) calloc (coords_length, sizeof (int)) : nullptr;
+ if (unlikely (coords_length && !normalized))
+ return;
+
+ hb_ot_var_normalize_variations (font->face,
+ variations, variations_length,
+ normalized, coords_length);
+ _hb_font_adopt_var_coords_normalized (font, normalized, coords_length);
+}
+
+/**
+ * hb_font_set_var_coords_design:
+ *
+ * Since: 1.4.2
+ */
+void
+hb_font_set_var_coords_design (hb_font_t *font,
+ const float *coords,
+ unsigned int coords_length)
+{
+ if (font->immutable)
+ return;
+
+ int *normalized = coords_length ? (int *) calloc (coords_length, sizeof (int)) : nullptr;
+ if (unlikely (coords_length && !normalized))
+ return;
+
+ hb_ot_var_normalize_coords (font->face, coords_length, coords, normalized);
+ _hb_font_adopt_var_coords_normalized (font, normalized, coords_length);
+}
+
+/**
+ * hb_font_set_var_coords_normalized:
+ *
+ * Since: 1.4.2
+ */
void
hb_font_set_var_coords_normalized (hb_font_t *font,
- int *coords, /* XXX 2.14 normalized */
+ const int *coords, /* 2.14 normalized */
unsigned int coords_length)
{
if (font->immutable)
return;
- /* Skip tail zero entries. */
- while (coords_length && !coords[coords_length - 1])
- coords_length--;
-
- int *copy = coords_length ? (int *) calloc (coords_length, sizeof (coords[0])) : NULL;
+ int *copy = coords_length ? (int *) calloc (coords_length, sizeof (coords[0])) : nullptr;
if (unlikely (coords_length && !copy))
return;
- free (font->coords);
-
if (coords_length)
memcpy (copy, coords, coords_length * sizeof (coords[0]));
- font->coords = copy;
- font->num_coords = coords_length;
+ _hb_font_adopt_var_coords_normalized (font, copy, coords_length);
+}
+
+/**
+ * hb_font_get_var_coords_normalized:
+ *
+ * Return value is valid as long as variation coordinates of the font
+ * are not modified.
+ *
+ * Since: 1.4.2
+ */
+const int *
+hb_font_get_var_coords_normalized (hb_font_t *font,
+ unsigned int *length)
+{
+ if (length)
+ *length = font->num_coords;
+
+ return font->coords;
}
@@ -1601,7 +1749,7 @@ trampoline_create (FuncType func,
trampoline_t *trampoline = (trampoline_t *) calloc (1, sizeof (trampoline_t));
if (unlikely (!trampoline))
- return NULL;
+ return nullptr;
trampoline->closure.user_data = user_data;
trampoline->closure.destroy = destroy;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font.h b/src/3rdparty/harfbuzz-ng/src/hb-font.h
index 8813286726..540cdcab95 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-font.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-font.h
@@ -563,6 +563,10 @@ hb_font_set_parent (hb_font_t *font,
HB_EXTERN hb_font_t *
hb_font_get_parent (hb_font_t *font);
+HB_EXTERN void
+hb_font_set_face (hb_font_t *font,
+ hb_face_t *face);
+
HB_EXTERN hb_face_t *
hb_font_get_face (hb_font_t *font);
@@ -603,12 +607,35 @@ hb_font_get_ppem (hb_font_t *font,
unsigned int *x_ppem,
unsigned int *y_ppem);
+/*
+ * Point size per EM. Used for optical-sizing in CoreText.
+ * A value of zero means "not set".
+ */
+HB_EXTERN void
+hb_font_set_ptem (hb_font_t *font, float ptem);
+
+HB_EXTERN float
+hb_font_get_ptem (hb_font_t *font);
+
+HB_EXTERN void
+hb_font_set_variations (hb_font_t *font,
+ const hb_variation_t *variations,
+ unsigned int variations_length);
+
+HB_EXTERN void
+hb_font_set_var_coords_design (hb_font_t *font,
+ const float *coords,
+ unsigned int coords_length);
HB_EXTERN void
hb_font_set_var_coords_normalized (hb_font_t *font,
- int *coords, /* XXX 2.14 normalized */
+ const int *coords, /* 2.14 normalized */
unsigned int coords_length);
+HB_EXTERN const int *
+hb_font_get_var_coords_normalized (hb_font_t *font,
+ unsigned int *length);
+
HB_END_DECLS
#endif /* HB_FONT_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-mutex-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-mutex-private.hh
index ed2703571c..49ed10e08a 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-mutex-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-mutex-private.hh
@@ -68,7 +68,7 @@ typedef CRITICAL_SECTION hb_mutex_impl_t;
#include <pthread.h>
typedef pthread_mutex_t hb_mutex_impl_t;
#define HB_MUTEX_IMPL_INIT PTHREAD_MUTEX_INITIALIZER
-#define hb_mutex_impl_init(M) pthread_mutex_init (M, NULL)
+#define hb_mutex_impl_init(M) pthread_mutex_init (M, nullptr)
#define hb_mutex_impl_lock(M) pthread_mutex_lock (M)
#define hb_mutex_impl_unlock(M) pthread_mutex_unlock (M)
#define hb_mutex_impl_finish(M) pthread_mutex_destroy (M)
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-object-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-object-private.hh
index 6b73ff92d0..baa1f8f05c 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-object-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-object-private.hh
@@ -33,18 +33,12 @@
#define HB_OBJECT_PRIVATE_HH
#include "hb-private.hh"
+#include "hb-debug.hh"
#include "hb-atomic-private.hh"
#include "hb-mutex-private.hh"
-/* Debug */
-
-#ifndef HB_DEBUG_OBJECT
-#define HB_DEBUG_OBJECT (HB_DEBUG+0)
-#endif
-
-
/* reference_count */
#define HB_REFERENCE_COUNT_INERT_VALUE -1
@@ -193,7 +187,7 @@ static inline void *hb_object_get_user_data (Type *obj,
hb_user_data_key_t *key)
{
if (unlikely (!obj || hb_object_is_inert (obj)))
- return NULL;
+ return nullptr;
assert (hb_object_is_valid (obj));
return obj->header.user_data.get (key);
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh
index 5357ddcf5b..644e0b40f6 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh
@@ -53,6 +53,9 @@ struct TTCHeader;
typedef struct TableRecord
{
+ int cmp (Tag t) const
+ { return t.cmp (tag); }
+
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -61,9 +64,9 @@ typedef struct TableRecord
Tag tag; /* 4-byte identifier. */
CheckSum checkSum; /* CheckSum for this table. */
- ULONG offset; /* Offset from beginning of TrueType font
+ UINT32 offset; /* Offset from beginning of TrueType font
* file. */
- ULONG length; /* Length of this table. */
+ UINT32 length; /* Length of this table. */
public:
DEFINE_SIZE_STATIC (16);
} OpenTypeTable;
@@ -73,27 +76,39 @@ typedef struct OffsetTable
friend struct OpenTypeFontFile;
inline unsigned int get_table_count (void) const
- { return numTables; }
+ { return tables.len; }
inline const TableRecord& get_table (unsigned int i) const
{
- if (unlikely (i >= numTables)) return Null(TableRecord);
return tables[i];
}
+ inline unsigned int get_table_tags (unsigned int start_offset,
+ unsigned int *table_count, /* IN/OUT */
+ hb_tag_t *table_tags /* OUT */) const
+ {
+ if (table_count)
+ {
+ if (start_offset >= tables.len)
+ *table_count = 0;
+ else
+ *table_count = MIN<unsigned int> (*table_count, tables.len - start_offset);
+
+ const TableRecord *sub_tables = tables.array + start_offset;
+ unsigned int count = *table_count;
+ for (unsigned int i = 0; i < count; i++)
+ table_tags[i] = sub_tables[i].tag;
+ }
+ return tables.len;
+ }
inline bool find_table_index (hb_tag_t tag, unsigned int *table_index) const
{
Tag t;
t.set (tag);
- unsigned int count = numTables;
- for (unsigned int i = 0; i < count; i++)
- {
- if (t == tables[i].tag)
- {
- if (table_index) *table_index = i;
- return true;
- }
- }
- if (table_index) *table_index = Index::NOT_FOUND_INDEX;
- return false;
+ /* Linear-search for small tables to work around fonts with unsorted
+ * table list. */
+ int i = tables.len < 64 ? tables.lsearch (t) : tables.bsearch (t);
+ if (table_index)
+ *table_index = i == -1 ? Index::NOT_FOUND_INDEX : (unsigned int) i;
+ return i != -1;
}
inline const TableRecord& get_table_by_tag (hb_tag_t tag) const
{
@@ -106,16 +121,13 @@ typedef struct OffsetTable
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && c->check_array (tables, TableRecord::static_size, numTables));
+ return_trace (c->check_struct (this) && tables.sanitize (c));
}
protected:
Tag sfnt_version; /* '\0\001\0\00' if TrueType / 'OTTO' if CFF */
- USHORT numTables; /* Number of tables. */
- USHORT searchRangeZ; /* (Maximum power of 2 <= numTables) x 16 */
- USHORT entrySelectorZ; /* Log2(maximum power of 2 <= numTables). */
- USHORT rangeShiftZ; /* NumTables x 16-searchRange. */
- TableRecord tables[VAR]; /* TableRecord entries. numTables items */
+ BinSearchArrayOf<TableRecord>
+ tables;
public:
DEFINE_SIZE_ARRAY (12, tables);
} OpenTypeFontFace;
@@ -142,7 +154,7 @@ struct TTCHeaderVersion1
Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */
FixedVersion<>version; /* Version of the TTC Header (1.0),
* 0x00010000u */
- ArrayOf<OffsetTo<OffsetTable, ULONG>, ULONG>
+ ArrayOf<LOffsetTo<OffsetTable>, UINT32>
table; /* Array of offsets to the OffsetTable for each font
* from the beginning of the file */
public:
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh
index 2cc1fb20d2..2f4e1b9e9e 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh
@@ -30,6 +30,8 @@
#define HB_OPEN_TYPE_PRIVATE_HH
#include "hb-private.hh"
+#include "hb-debug.hh"
+#include "hb-face-private.hh"
namespace OT {
@@ -84,7 +86,7 @@ static inline Type& StructAfter(TObject &X)
#define _DEFINE_INSTANCE_ASSERTION1(_line, _assertion) \
inline void _instance_assertion_on_line_##_line (void) const \
{ \
- ASSERT_STATIC (_assertion); \
+ static_assert ((_assertion), ""); \
ASSERT_INSTANCE_POD (*this); /* Make sure it's POD. */ \
}
# define _DEFINE_INSTANCE_ASSERTION0(_line, _assertion) _DEFINE_INSTANCE_ASSERTION1 (_line, _assertion)
@@ -129,14 +131,16 @@ static inline Type& StructAfter(TObject &X)
*/
/* Global nul-content Null pool. Enlarge as necessary. */
-/* TODO This really should be a extern HB_INTERNAL and defined somewhere... */
-static const void *_NullPool[(256+8) / sizeof (void *)];
+
+#define HB_NULL_POOL_SIZE 264
+static_assert (HB_NULL_POOL_SIZE % sizeof (void *) == 0, "Align HB_NULL_POOL_SIZE.");
+extern HB_INTERNAL const void * const _hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)];
/* Generic nul-content Null objects. */
template <typename Type>
static inline const Type& Null (void) {
- ASSERT_STATIC (sizeof (Type) <= sizeof (_NullPool));
- return *CastP<Type> (_NullPool);
+ static_assert (sizeof (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE.");
+ return *CastP<Type> (_hb_NullPool);
}
/* Specializaiton for arbitrary-content arbitrary-sized Null objects. */
@@ -146,7 +150,7 @@ template <> \
/*static*/ inline const Type& Null<Type> (void) { \
return *CastP<Type> (_Null##Type); \
} /* The following line really exists such that we end in a place needing semicolon */ \
-ASSERT_STATIC (Type::min_size + 1 <= sizeof (_Null##Type))
+static_assert (Type::min_size + 1 <= sizeof (_Null##Type), "Null pool too small. Enlarge.")
/* Accessor macro. */
#define Null(Type) Null<Type>()
@@ -171,16 +175,6 @@ struct hb_dispatch_context_t
* Sanitize
*/
-#ifndef HB_DEBUG_SANITIZE
-#define HB_DEBUG_SANITIZE (HB_DEBUG+0)
-#endif
-
-
-#define TRACE_SANITIZE(this) \
- hb_auto_trace_t<HB_DEBUG_SANITIZE, bool> trace \
- (&c->debug_depth, c->get_name (), this, HB_FUNC, \
- "");
-
/* This limits sanitizing time on really broken fonts. */
#ifndef HB_SANITIZE_MAX_EDITS
#define HB_SANITIZE_MAX_EDITS 32
@@ -191,9 +185,9 @@ struct hb_sanitize_context_t :
{
inline hb_sanitize_context_t (void) :
debug_depth (0),
- start (NULL), end (NULL),
+ start (nullptr), end (nullptr),
writable (false), edit_count (0),
- blob (NULL) {}
+ blob (nullptr) {}
inline const char *get_name (void) { return "SANITIZE"; }
template <typename T, typename F>
@@ -213,7 +207,7 @@ struct hb_sanitize_context_t :
inline void start_processing (void)
{
- this->start = hb_blob_get_data (this->blob, NULL);
+ this->start = hb_blob_get_data (this->blob, nullptr);
this->end = this->start + hb_blob_get_length (this->blob);
assert (this->start <= this->end); /* Must not overflow. */
this->edit_count = 0;
@@ -232,8 +226,8 @@ struct hb_sanitize_context_t :
this->start, this->end, this->edit_count);
hb_blob_destroy (this->blob);
- this->blob = NULL;
- this->start = this->end = NULL;
+ this->blob = nullptr;
+ this->start = this->end = nullptr;
}
inline bool check_range (const void *base, unsigned int len) const
@@ -348,7 +342,7 @@ struct Sanitizer
} else {
unsigned int edit_count = c->edit_count;
if (edit_count && !c->writable) {
- c->start = hb_blob_get_data_writable (blob, NULL);
+ c->start = hb_blob_get_data_writable (blob, nullptr);
c->end = c->start + hb_blob_get_length (blob);
if (c->start) {
@@ -373,7 +367,7 @@ struct Sanitizer
static const Type* lock_instance (hb_blob_t *blob) {
hb_blob_make_immutable (blob);
- const char *base = hb_blob_get_data (blob, NULL);
+ const char *base = hb_blob_get_data (blob, nullptr);
return unlikely (!base) ? &Null(Type) : CastP<Type> (base);
}
};
@@ -384,16 +378,6 @@ struct Sanitizer
* Serialize
*/
-#ifndef HB_DEBUG_SERIALIZE
-#define HB_DEBUG_SERIALIZE (HB_DEBUG+0)
-#endif
-
-
-#define TRACE_SERIALIZE(this) \
- hb_auto_trace_t<HB_DEBUG_SERIALIZE, bool> trace \
- (&c->debug_depth, "SERIALIZE", c, HB_FUNC, \
- "");
-
struct hb_serialize_context_t
{
@@ -444,7 +428,7 @@ struct hb_serialize_context_t
{
if (unlikely (this->ran_out_of_room || this->end - this->head < ptrdiff_t (size))) {
this->ran_out_of_room = true;
- return NULL;
+ return nullptr;
}
memset (this->head, 0, size);
char *ret = this->head;
@@ -470,7 +454,7 @@ struct hb_serialize_context_t
{
unsigned int size = obj.get_size ();
Type *ret = this->allocate_size<Type> (size);
- if (unlikely (!ret)) return NULL;
+ if (unlikely (!ret)) return nullptr;
memcpy (ret, obj, size);
return ret;
}
@@ -480,7 +464,7 @@ struct hb_serialize_context_t
{
unsigned int size = obj.min_size;
assert (this->start <= (char *) &obj && (char *) &obj <= this->head && (char *) &obj + size >= this->head);
- if (unlikely (!this->allocate_size<Type> (((char *) &obj) + size - this->head))) return NULL;
+ if (unlikely (!this->allocate_size<Type> (((char *) &obj) + size - this->head))) return nullptr;
return reinterpret_cast<Type *> (&obj);
}
@@ -489,7 +473,7 @@ struct hb_serialize_context_t
{
unsigned int size = obj.get_size ();
assert (this->start < (char *) &obj && (char *) &obj <= this->head && (char *) &obj + size >= this->head);
- if (unlikely (!this->allocate_size<Type> (((char *) &obj) + size - this->head))) return NULL;
+ if (unlikely (!this->allocate_size<Type> (((char *) &obj) + size - this->head))) return nullptr;
return reinterpret_cast<Type *> (&obj);
}
@@ -631,10 +615,11 @@ struct IntType
inline bool operator == (const IntType<Type,Size> &o) const { return (Type) v == (Type) o.v; }
inline bool operator != (const IntType<Type,Size> &o) const { return !(*this == o); }
static inline int cmp (const IntType<Type,Size> *a, const IntType<Type,Size> *b) { return b->cmp (*a); }
- inline int cmp (Type a) const
+ template <typename Type2>
+ inline int cmp (Type2 a) const
{
Type b = v;
- if (sizeof (Type) < sizeof (int))
+ if (sizeof (Type) < sizeof (int) && sizeof (Type2) < sizeof (int))
return (int) a - (int) b;
else
return a < b ? -1 : a == b ? 0 : +1;
@@ -650,23 +635,22 @@ struct IntType
DEFINE_SIZE_STATIC (Size);
};
-typedef IntType<int8_t , 1> CHAR; /* 8-bit signed integer. */
-typedef IntType<uint8_t , 1> BYTE; /* 8-bit unsigned integer. */
-typedef IntType<int8_t , 1> INT8; /* 8-bit signed integer. */
-typedef IntType<uint16_t, 2> USHORT; /* 16-bit unsigned integer. */
-typedef IntType<int16_t, 2> SHORT; /* 16-bit signed integer. */
-typedef IntType<uint32_t, 4> ULONG; /* 32-bit unsigned integer. */
-typedef IntType<int32_t, 4> LONG; /* 32-bit signed integer. */
+typedef IntType<uint8_t, 1> UINT8; /* 8-bit unsigned integer. */
+typedef IntType<int8_t, 1> INT8; /* 8-bit signed integer. */
+typedef IntType<uint16_t, 2> UINT16; /* 16-bit unsigned integer. */
+typedef IntType<int16_t, 2> INT16; /* 16-bit signed integer. */
+typedef IntType<uint32_t, 4> UINT32; /* 32-bit unsigned integer. */
+typedef IntType<int32_t, 4> INT32; /* 32-bit signed integer. */
typedef IntType<uint32_t, 3> UINT24; /* 24-bit unsigned integer. */
-/* 16-bit signed integer (SHORT) that describes a quantity in FUnits. */
-typedef SHORT FWORD;
+/* 16-bit signed integer (INT16) that describes a quantity in FUnits. */
+typedef INT16 FWORD;
-/* 16-bit unsigned integer (USHORT) that describes a quantity in FUnits. */
-typedef USHORT UFWORD;
+/* 16-bit unsigned integer (UINT16) that describes a quantity in FUnits. */
+typedef UINT16 UFWORD;
/* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */
-struct F2DOT14 : SHORT
+struct F2DOT14 : INT16
{
//inline float to_float (void) const { return ???; }
//inline void set_float (float f) { v.set (f * ???); }
@@ -675,7 +659,7 @@ struct F2DOT14 : SHORT
};
/* 32-bit signed fixed-point number (16.16). */
-struct Fixed: LONG
+struct Fixed: INT32
{
//inline float to_float (void) const { return ???; }
//inline void set_float (float f) { v.set (f * ???); }
@@ -693,15 +677,15 @@ struct LONGDATETIME
return_trace (likely (c->check_struct (this)));
}
protected:
- LONG major;
- ULONG minor;
+ INT32 major;
+ UINT32 minor;
public:
DEFINE_SIZE_STATIC (8);
};
/* Array of four uint8s (length = 32 bits) used to identify a script, language
* system, feature, or baseline */
-struct Tag : ULONG
+struct Tag : UINT32
{
/* What the char* converters return is NOT nul-terminated. Print using "%.4s" */
inline operator const char* (void) const { return reinterpret_cast<const char *> (&this->v); }
@@ -712,19 +696,16 @@ struct Tag : ULONG
DEFINE_NULL_DATA (Tag, " ");
/* Glyph index number, same as uint16 (length = 16 bits) */
-struct GlyphID : USHORT {
- static inline int cmp (const GlyphID *a, const GlyphID *b) { return b->USHORT::cmp (*a); }
- inline int cmp (hb_codepoint_t a) const { return (int) a - (int) *this; }
-};
+typedef UINT16 GlyphID;
/* Script/language-system/feature index */
-struct Index : USHORT {
+struct Index : UINT16 {
static const unsigned int NOT_FOUND_INDEX = 0xFFFFu;
};
DEFINE_NULL_DATA (Index, "\xff\xff");
/* Offset, Null offset = 0 */
-template <typename Type=USHORT>
+template <typename Type>
struct Offset : Type
{
inline bool is_null (void) const { return 0 == *this; }
@@ -732,15 +713,18 @@ struct Offset : Type
DEFINE_SIZE_STATIC (sizeof(Type));
};
+typedef Offset<UINT16> Offset16;
+typedef Offset<UINT32> Offset32;
+
/* CheckSum */
-struct CheckSum : ULONG
+struct CheckSum : UINT32
{
/* This is reference implementation from the spec. */
- static inline uint32_t CalcTableChecksum (const ULONG *Table, uint32_t Length)
+ static inline uint32_t CalcTableChecksum (const UINT32 *Table, uint32_t Length)
{
uint32_t Sum = 0L;
- const ULONG *EndPtr = Table+((Length+3) & ~3) / ULONG::static_size;
+ const UINT32 *EndPtr = Table+((Length+3) & ~3) / UINT32::static_size;
while (Table < EndPtr)
Sum += *Table++;
@@ -749,7 +733,7 @@ struct CheckSum : ULONG
/* Note: data should be 4byte aligned and have 4byte padding at the end. */
inline void set_for_data (const void *data, unsigned int length)
- { set (CalcTableChecksum ((const ULONG *) data, length)); }
+ { set (CalcTableChecksum ((const UINT32 *) data, length)); }
public:
DEFINE_SIZE_STATIC (4);
@@ -760,7 +744,7 @@ struct CheckSum : ULONG
* Version Numbers
*/
-template <typename FixedType=USHORT>
+template <typename FixedType=UINT16>
struct FixedVersion
{
inline uint32_t to_int (void) const { return (major << (sizeof(FixedType) * 8)) + minor; }
@@ -784,7 +768,7 @@ struct FixedVersion
* Use: (base+offset)
*/
-template <typename Type, typename OffsetType=USHORT>
+template <typename Type, typename OffsetType=UINT16>
struct OffsetTo : Offset<OffsetType>
{
inline const Type& operator () (const void *base) const
@@ -829,6 +813,7 @@ struct OffsetTo : Offset<OffsetType>
}
DEFINE_SIZE_STATIC (sizeof(OffsetType));
};
+template <typename Type> struct LOffsetTo : OffsetTo<Type, UINT32> {};
template <typename Base, typename OffsetType, typename Type>
static inline const Type& operator + (const Base &base, const OffsetTo<Type, OffsetType> &offset) { return offset (base); }
template <typename Base, typename OffsetType, typename Type>
@@ -840,7 +825,7 @@ static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType> &offset)
*/
/* An array with a number of elements. */
-template <typename Type, typename LenType=USHORT>
+template <typename Type, typename LenType=UINT16>
struct ArrayOf
{
const Type *sub_array (unsigned int start_offset, unsigned int *pcount /* IN/OUT */) const
@@ -941,7 +926,7 @@ struct ArrayOf
inline bool sanitize_shallow (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && c->check_array (array, Type::static_size, len));
+ return_trace (len.sanitize (c) && c->check_array (array, Type::static_size, len));
}
public:
@@ -950,9 +935,10 @@ struct ArrayOf
public:
DEFINE_SIZE_ARRAY (sizeof (LenType), array);
};
+template <typename Type> struct LArrayOf : ArrayOf<Type, UINT32> {};
/* Array of Offset's */
-template <typename Type, typename OffsetType=USHORT>
+template <typename Type, typename OffsetType=UINT16>
struct OffsetArrayOf : ArrayOf<OffsetTo<Type, OffsetType> > {};
/* Array of offsets relative to the beginning of the array itself. */
@@ -980,7 +966,7 @@ struct OffsetListOf : OffsetArrayOf<Type>
/* An array starting at second element. */
-template <typename Type, typename LenType=USHORT>
+template <typename Type, typename LenType=UINT16>
struct HeadlessArrayOf
{
inline const Type& operator [] (unsigned int i) const
@@ -1006,12 +992,6 @@ struct HeadlessArrayOf
return_trace (true);
}
- inline bool sanitize_shallow (hb_sanitize_context_t *c) const
- {
- return c->check_struct (this)
- && c->check_array (this, Type::static_size, len);
- }
-
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -1029,6 +1009,15 @@ struct HeadlessArrayOf
return_trace (true);
}
+ private:
+ inline bool sanitize_shallow (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (len.sanitize (c) &&
+ (!len || c->check_array (array, Type::static_size, len - 1)));
+ }
+
+ public:
LenType len;
Type array[VAR];
public:
@@ -1036,19 +1025,22 @@ struct HeadlessArrayOf
};
-/* An array with sorted elements. Supports binary searching. */
-template <typename Type, typename LenType=USHORT>
+/*
+ * An array with sorted elements. Supports binary searching.
+ */
+template <typename Type, typename LenType=UINT16>
struct SortedArrayOf : ArrayOf<Type, LenType>
{
template <typename SearchType>
inline int bsearch (const SearchType &x) const
{
/* Hand-coded bsearch here since this is in the hot inner loop. */
+ const Type *array = this->array;
int min = 0, max = (int) this->len - 1;
while (min <= max)
{
int mid = (min + max) / 2;
- int c = this->array[mid].cmp (x);
+ int c = array[mid].cmp (x);
if (c < 0)
max = mid - 1;
else if (c > 0)
@@ -1060,6 +1052,131 @@ struct SortedArrayOf : ArrayOf<Type, LenType>
}
};
+/*
+ * Binary-search arrays
+ */
+
+struct BinSearchHeader
+{
+ inline operator uint32_t (void) const { return len; }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this));
+ }
+
+ protected:
+ UINT16 len;
+ UINT16 searchRangeZ;
+ UINT16 entrySelectorZ;
+ UINT16 rangeShiftZ;
+
+ public:
+ DEFINE_SIZE_STATIC (8);
+};
+
+template <typename Type>
+struct BinSearchArrayOf : SortedArrayOf<Type, BinSearchHeader> {};
+
+
+/* Lazy struct and blob loaders. */
+
+/* Logic is shared between hb_lazy_loader_t and hb_lazy_table_loader_t */
+template <typename T>
+struct hb_lazy_loader_t
+{
+ inline void init (hb_face_t *face_)
+ {
+ face = face_;
+ instance = nullptr;
+ }
+
+ inline void fini (void)
+ {
+ if (instance && instance != &OT::Null(T))
+ {
+ instance->fini();
+ free (instance);
+ }
+ }
+
+ inline const T* get (void) const
+ {
+ retry:
+ T *p = (T *) hb_atomic_ptr_get (&instance);
+ if (unlikely (!p))
+ {
+ p = (T *) calloc (1, sizeof (T));
+ if (unlikely (!p))
+ p = const_cast<T *> (&OT::Null(T));
+ else
+ p->init (face);
+ if (unlikely (!hb_atomic_ptr_cmpexch (const_cast<T **>(&instance), nullptr, p)))
+ {
+ if (p != &OT::Null(T))
+ p->fini ();
+ goto retry;
+ }
+ }
+ return p;
+ }
+
+ inline const T* operator-> (void) const
+ {
+ return get ();
+ }
+
+ private:
+ hb_face_t *face;
+ T *instance;
+};
+
+/* Logic is shared between hb_lazy_loader_t and hb_lazy_table_loader_t */
+template <typename T>
+struct hb_lazy_table_loader_t
+{
+ inline void init (hb_face_t *face_)
+ {
+ face = face_;
+ instance = nullptr;
+ blob = nullptr;
+ }
+
+ inline void fini (void)
+ {
+ hb_blob_destroy (blob);
+ }
+
+ inline const T* get (void) const
+ {
+ retry:
+ T *p = (T *) hb_atomic_ptr_get (&instance);
+ if (unlikely (!p))
+ {
+ hb_blob_t *blob_ = OT::Sanitizer<T>::sanitize (face->reference_table (T::tableTag));
+ p = const_cast<T *>(OT::Sanitizer<T>::lock_instance (blob_));
+ if (!hb_atomic_ptr_cmpexch (const_cast<T **>(&instance), nullptr, p))
+ {
+ hb_blob_destroy (blob_);
+ goto retry;
+ }
+ blob = blob_;
+ }
+ return p;
+ }
+
+ inline const T* operator-> (void) const
+ {
+ return get();
+ }
+
+ private:
+ hb_face_t *face;
+ T *instance;
+ mutable hb_blob_t *blob;
+};
+
} /* namespace OT */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cbdt-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cbdt-table.hh
index 52897abd3a..415625e5f8 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cbdt-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cbdt-table.hh
@@ -47,20 +47,20 @@ struct SmallGlyphMetrics
extents->height = -height;
}
- BYTE height;
- BYTE width;
- CHAR bearingX;
- CHAR bearingY;
- BYTE advance;
+ UINT8 height;
+ UINT8 width;
+ INT8 bearingX;
+ INT8 bearingY;
+ UINT8 advance;
DEFINE_SIZE_STATIC(5);
};
struct BigGlyphMetrics : SmallGlyphMetrics
{
- CHAR vertBearingX;
- CHAR vertBearingY;
- BYTE vertAdvance;
+ INT8 vertBearingX;
+ INT8 vertBearingY;
+ UINT8 vertAdvance;
DEFINE_SIZE_STATIC(8);
};
@@ -73,18 +73,18 @@ struct SBitLineMetrics
return_trace (c->check_struct (this));
}
- CHAR ascender;
- CHAR decender;
- BYTE widthMax;
- CHAR caretSlopeNumerator;
- CHAR caretSlopeDenominator;
- CHAR caretOffset;
- CHAR minOriginSB;
- CHAR minAdvanceSB;
- CHAR maxBeforeBL;
- CHAR minAfterBL;
- CHAR padding1;
- CHAR padding2;
+ INT8 ascender;
+ INT8 decender;
+ UINT8 widthMax;
+ INT8 caretSlopeNumerator;
+ INT8 caretSlopeDenominator;
+ INT8 caretOffset;
+ INT8 minOriginSB;
+ INT8 minAdvanceSB;
+ INT8 maxBeforeBL;
+ INT8 minAfterBL;
+ INT8 padding1;
+ INT8 padding2;
DEFINE_SIZE_STATIC(12);
};
@@ -102,9 +102,9 @@ struct IndexSubtableHeader
return_trace (c->check_struct (this));
}
- USHORT indexFormat;
- USHORT imageFormat;
- ULONG imageDataOffset;
+ UINT16 indexFormat;
+ UINT16 imageFormat;
+ UINT32 imageDataOffset;
DEFINE_SIZE_STATIC(8);
};
@@ -137,8 +137,8 @@ struct IndexSubtableFormat1Or3
DEFINE_SIZE_ARRAY(8, offsetArrayZ);
};
-struct IndexSubtableFormat1 : IndexSubtableFormat1Or3<ULONG> {};
-struct IndexSubtableFormat3 : IndexSubtableFormat1Or3<USHORT> {};
+struct IndexSubtableFormat1 : IndexSubtableFormat1Or3<UINT32> {};
+struct IndexSubtableFormat3 : IndexSubtableFormat1Or3<UINT16> {};
struct IndexSubtable
{
@@ -214,9 +214,9 @@ struct IndexSubtableRecord
offset, length, format);
}
- USHORT firstGlyphIndex;
- USHORT lastGlyphIndex;
- OffsetTo<IndexSubtable, ULONG> offsetToSubtable;
+ UINT16 firstGlyphIndex;
+ UINT16 lastGlyphIndex;
+ LOffsetTo<IndexSubtable> offsetToSubtable;
DEFINE_SIZE_STATIC(8);
};
@@ -245,7 +245,7 @@ struct IndexSubtableArray
return &indexSubtablesZ[i];
}
}
- return NULL;
+ return nullptr;
}
protected:
@@ -275,20 +275,20 @@ struct BitmapSizeTable
}
protected:
- OffsetTo<IndexSubtableArray, ULONG> indexSubtableArrayOffset;
- ULONG indexTablesSize;
- ULONG numberOfIndexSubtables;
- ULONG colorRef;
+ LOffsetTo<IndexSubtableArray> indexSubtableArrayOffset;
+ UINT32 indexTablesSize;
+ UINT32 numberOfIndexSubtables;
+ UINT32 colorRef;
SBitLineMetrics horizontal;
SBitLineMetrics vertical;
- USHORT startGlyphIndex;
- USHORT endGlyphIndex;
- BYTE ppemX;
- BYTE ppemY;
- BYTE bitDepth;
- CHAR flags;
-
-public:
+ UINT16 startGlyphIndex;
+ UINT16 endGlyphIndex;
+ UINT8 ppemX;
+ UINT8 ppemY;
+ UINT8 bitDepth;
+ INT8 flags;
+
+ public:
DEFINE_SIZE_STATIC(48);
};
@@ -300,8 +300,8 @@ public:
struct GlyphBitmapDataFormat17
{
SmallGlyphMetrics glyphMetrics;
- ULONG dataLen;
- BYTE dataZ[VAR];
+ UINT32 dataLen;
+ UINT8 dataZ[VAR];
DEFINE_SIZE_ARRAY(9, dataZ);
};
@@ -315,6 +315,8 @@ struct GlyphBitmapDataFormat17
struct CBLC
{
+ friend struct CBDT;
+
static const hb_tag_t tableTag = HB_OT_TAG_CBLC;
inline bool sanitize (hb_sanitize_context_t *c) const
@@ -325,7 +327,7 @@ struct CBLC
sizeTables.sanitize (c, this));
}
- public:
+ protected:
const IndexSubtableRecord *find_table (hb_codepoint_t glyph,
unsigned int *x_ppem, unsigned int *y_ppem) const
{
@@ -344,12 +346,12 @@ struct CBLC
}
}
- return NULL;
+ return nullptr;
}
protected:
- FixedVersion<>version;
- ArrayOf<BitmapSizeTable, ULONG> sizeTables;
+ FixedVersion<> version;
+ LArrayOf<BitmapSizeTable> sizeTables;
public:
DEFINE_SIZE_ARRAY(8, sizeTables);
@@ -371,9 +373,94 @@ struct CBDT
likely (version.major == 2 || version.major == 3));
}
+ struct accelerator_t
+ {
+ inline void init (hb_face_t *face)
+ {
+ upem = face->get_upem();
+
+ cblc_blob = Sanitizer<CBLC>::sanitize (face->reference_table (HB_OT_TAG_CBLC));
+ cbdt_blob = Sanitizer<CBDT>::sanitize (face->reference_table (HB_OT_TAG_CBDT));
+ cbdt_len = hb_blob_get_length (cbdt_blob);
+
+ if (hb_blob_get_length (cblc_blob) == 0) {
+ cblc = nullptr;
+ cbdt = nullptr;
+ return; /* Not a bitmap font. */
+ }
+ cblc = Sanitizer<CBLC>::lock_instance (cblc_blob);
+ cbdt = Sanitizer<CBDT>::lock_instance (cbdt_blob);
+
+ }
+
+ inline void fini (void)
+ {
+ hb_blob_destroy (this->cblc_blob);
+ hb_blob_destroy (this->cbdt_blob);
+ }
+
+ inline bool get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
+ {
+ unsigned int x_ppem = upem, y_ppem = upem; /* TODO Use font ppem if available. */
+
+ if (!cblc)
+ return false; // Not a color bitmap font.
+
+ const IndexSubtableRecord *subtable_record = this->cblc->find_table(glyph, &x_ppem, &y_ppem);
+ if (!subtable_record || !x_ppem || !y_ppem)
+ return false;
+
+ if (subtable_record->get_extents (extents))
+ return true;
+
+ unsigned int image_offset = 0, image_length = 0, image_format = 0;
+ if (!subtable_record->get_image_data (glyph, &image_offset, &image_length, &image_format))
+ return false;
+
+ {
+ if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length))
+ return false;
+
+ switch (image_format)
+ {
+ case 17: {
+ if (unlikely (image_length < GlyphBitmapDataFormat17::min_size))
+ return false;
+
+ const GlyphBitmapDataFormat17& glyphFormat17 =
+ StructAtOffset<GlyphBitmapDataFormat17> (this->cbdt, image_offset);
+ glyphFormat17.glyphMetrics.get_extents (extents);
+ }
+ break;
+ default:
+ // TODO: Support other image formats.
+ return false;
+ }
+ }
+
+ /* Convert to the font units. */
+ extents->x_bearing *= upem / (float) x_ppem;
+ extents->y_bearing *= upem / (float) y_ppem;
+ extents->width *= upem / (float) x_ppem;
+ extents->height *= upem / (float) y_ppem;
+
+ return true;
+ }
+
+ private:
+ hb_blob_t *cblc_blob;
+ hb_blob_t *cbdt_blob;
+ const CBLC *cblc;
+ const CBDT *cbdt;
+
+ unsigned int cbdt_len;
+ unsigned int upem;
+ };
+
+
protected:
FixedVersion<>version;
- BYTE dataZ[VAR];
+ UINT8 dataZ[VAR];
public:
DEFINE_SIZE_ARRAY(4, dataZ);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh
index d7a94a1ef0..883d7b3f0b 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh
@@ -58,10 +58,10 @@ struct CmapSubtableFormat0
}
protected:
- USHORT format; /* Format number is set to 0. */
- USHORT lengthZ; /* Byte length of this subtable. */
- USHORT languageZ; /* Ignore. */
- BYTE glyphIdArray[256];/* An array that maps character
+ UINT16 format; /* Format number is set to 0. */
+ UINT16 lengthZ; /* Byte length of this subtable. */
+ UINT16 languageZ; /* Ignore. */
+ UINT8 glyphIdArray[256];/* An array that maps character
* code to glyph index values. */
public:
DEFINE_SIZE_STATIC (6 + 256);
@@ -88,8 +88,8 @@ struct CmapSubtableFormat4
/* Custom two-array bsearch. */
int min = 0, max = (int) thiz->segCount - 1;
- const USHORT *startCount = thiz->startCount;
- const USHORT *endCount = thiz->endCount;
+ const UINT16 *startCount = thiz->startCount;
+ const UINT16 *endCount = thiz->endCount;
unsigned int i;
while (min <= max)
{
@@ -127,11 +127,11 @@ struct CmapSubtableFormat4
return true;
}
- const USHORT *endCount;
- const USHORT *startCount;
- const USHORT *idDelta;
- const USHORT *idRangeOffset;
- const USHORT *glyphIdArray;
+ const UINT16 *endCount;
+ const UINT16 *startCount;
+ const UINT16 *idDelta;
+ const UINT16 *idRangeOffset;
+ const UINT16 *glyphIdArray;
unsigned int segCount;
unsigned int glyphIdArrayLength;
};
@@ -165,24 +165,24 @@ struct CmapSubtableFormat4
}
protected:
- USHORT format; /* Format number is set to 4. */
- USHORT length; /* This is the length in bytes of the
+ UINT16 format; /* Format number is set to 4. */
+ UINT16 length; /* This is the length in bytes of the
* subtable. */
- USHORT languageZ; /* Ignore. */
- USHORT segCountX2; /* 2 x segCount. */
- USHORT searchRangeZ; /* 2 * (2**floor(log2(segCount))) */
- USHORT entrySelectorZ; /* log2(searchRange/2) */
- USHORT rangeShiftZ; /* 2 x segCount - searchRange */
+ UINT16 languageZ; /* Ignore. */
+ UINT16 segCountX2; /* 2 x segCount. */
+ UINT16 searchRangeZ; /* 2 * (2**floor(log2(segCount))) */
+ UINT16 entrySelectorZ; /* log2(searchRange/2) */
+ UINT16 rangeShiftZ; /* 2 x segCount - searchRange */
- USHORT values[VAR];
+ UINT16 values[VAR];
#if 0
- USHORT endCount[segCount]; /* End characterCode for each segment,
+ UINT16 endCount[segCount]; /* End characterCode for each segment,
* last=0xFFFFu. */
- USHORT reservedPad; /* Set to 0. */
- USHORT startCount[segCount]; /* Start character code for each segment. */
- SHORT idDelta[segCount]; /* Delta for all character codes in segment. */
- USHORT idRangeOffset[segCount];/* Offsets into glyphIdArray or 0 */
- USHORT glyphIdArray[VAR]; /* Glyph index array (arbitrary length) */
+ UINT16 reservedPad; /* Set to 0. */
+ UINT16 startCount[segCount]; /* Start character code for each segment. */
+ INT16 idDelta[segCount]; /* Delta for all character codes in segment. */
+ UINT16 idRangeOffset[segCount];/* Offsets into glyphIdArray or 0 */
+ UINT16 glyphIdArray[VAR]; /* Glyph index array (arbitrary length) */
#endif
public:
@@ -208,9 +208,9 @@ struct CmapSubtableLongGroup
}
private:
- ULONG startCharCode; /* First character code in this group. */
- ULONG endCharCode; /* Last character code in this group. */
- ULONG glyphID; /* Glyph index; interpretation depends on
+ UINT32 startCharCode; /* First character code in this group. */
+ UINT32 endCharCode; /* Last character code in this group. */
+ UINT32 glyphID; /* Glyph index; interpretation depends on
* subtable format. */
public:
DEFINE_SIZE_STATIC (12);
@@ -247,8 +247,8 @@ struct CmapSubtableTrimmed
DEFINE_SIZE_ARRAY (5 * sizeof (UINT), glyphIdArray);
};
-struct CmapSubtableFormat6 : CmapSubtableTrimmed<USHORT> {};
-struct CmapSubtableFormat10 : CmapSubtableTrimmed<ULONG > {};
+struct CmapSubtableFormat6 : CmapSubtableTrimmed<UINT16> {};
+struct CmapSubtableFormat10 : CmapSubtableTrimmed<UINT32 > {};
template <typename T>
struct CmapSubtableLongSegmented
@@ -269,11 +269,11 @@ struct CmapSubtableLongSegmented
}
protected:
- USHORT format; /* Subtable format; set to 12. */
- USHORT reservedZ; /* Reserved; set to 0. */
- ULONG lengthZ; /* Byte length of this subtable. */
- ULONG languageZ; /* Ignore. */
- SortedArrayOf<CmapSubtableLongGroup, ULONG>
+ UINT16 format; /* Subtable format; set to 12. */
+ UINT16 reservedZ; /* Reserved; set to 0. */
+ UINT32 lengthZ; /* Byte length of this subtable. */
+ UINT32 languageZ; /* Ignore. */
+ SortedArrayOf<CmapSubtableLongGroup, UINT32>
groups; /* Groupings. */
public:
DEFINE_SIZE_ARRAY (16, groups);
@@ -316,13 +316,13 @@ struct UnicodeValueRange
}
UINT24 startUnicodeValue; /* First value in this range. */
- BYTE additionalCount; /* Number of additional values in this
+ UINT8 additionalCount; /* Number of additional values in this
* range. */
public:
DEFINE_SIZE_STATIC (4);
};
-typedef SortedArrayOf<UnicodeValueRange, ULONG> DefaultUVS;
+typedef SortedArrayOf<UnicodeValueRange, UINT32> DefaultUVS;
struct UVSMapping
{
@@ -343,7 +343,7 @@ struct UVSMapping
DEFINE_SIZE_STATIC (5);
};
-typedef SortedArrayOf<UVSMapping, ULONG> NonDefaultUVS;
+typedef SortedArrayOf<UVSMapping, UINT32> NonDefaultUVS;
struct VariationSelectorRecord
{
@@ -380,9 +380,9 @@ struct VariationSelectorRecord
}
UINT24 varSelector; /* Variation selector. */
- OffsetTo<DefaultUVS, ULONG>
+ LOffsetTo<DefaultUVS>
defaultUVS; /* Offset to Default UVS Table. May be 0. */
- OffsetTo<NonDefaultUVS, ULONG>
+ LOffsetTo<NonDefaultUVS>
nonDefaultUVS; /* Offset to Non-Default UVS Table. May be 0. */
public:
DEFINE_SIZE_STATIC (11);
@@ -405,9 +405,9 @@ struct CmapSubtableFormat14
}
protected:
- USHORT format; /* Format number is set to 14. */
- ULONG lengthZ; /* Byte length of this subtable. */
- SortedArrayOf<VariationSelectorRecord, ULONG>
+ UINT16 format; /* Format number is set to 14. */
+ UINT32 lengthZ; /* Byte length of this subtable. */
+ SortedArrayOf<VariationSelectorRecord, UINT32>
record; /* Variation selector records; sorted
* in increasing order of `varSelector'. */
public:
@@ -451,7 +451,7 @@ struct CmapSubtable
public:
union {
- USHORT format; /* Format identifier */
+ UINT16 format; /* Format identifier */
CmapSubtableFormat0 format0;
CmapSubtableFormat4 format4;
CmapSubtableFormat6 format6;
@@ -484,9 +484,9 @@ struct EncodingRecord
subtable.sanitize (c, base));
}
- USHORT platformID; /* Platform ID. */
- USHORT encodingID; /* Platform-specific encoding ID. */
- OffsetTo<CmapSubtable, ULONG>
+ UINT16 platformID; /* Platform ID. */
+ UINT16 encodingID; /* Platform-specific encoding ID. */
+ LOffsetTo<CmapSubtable>
subtable; /* Byte offset from beginning of table to the subtable for this encoding. */
public:
DEFINE_SIZE_STATIC (8);
@@ -496,6 +496,146 @@ struct cmap
{
static const hb_tag_t tableTag = HB_OT_TAG_cmap;
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ likely (version == 0) &&
+ encodingRecord.sanitize (c, this));
+ }
+
+ struct accelerator_t
+ {
+ inline void init (hb_face_t *face)
+ {
+ this->blob = OT::Sanitizer<OT::cmap>::sanitize (face->reference_table (HB_OT_TAG_cmap));
+ const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::lock_instance (this->blob);
+ const OT::CmapSubtable *subtable = nullptr;
+ const OT::CmapSubtableFormat14 *subtable_uvs = nullptr;
+
+ bool symbol = false;
+ /* 32-bit subtables. */
+ if (!subtable) subtable = cmap->find_subtable (3, 10);
+ if (!subtable) subtable = cmap->find_subtable (0, 6);
+ if (!subtable) subtable = cmap->find_subtable (0, 4);
+ /* 16-bit subtables. */
+ if (!subtable) subtable = cmap->find_subtable (3, 1);
+ if (!subtable) subtable = cmap->find_subtable (0, 3);
+ if (!subtable) subtable = cmap->find_subtable (0, 2);
+ if (!subtable) subtable = cmap->find_subtable (0, 1);
+ if (!subtable) subtable = cmap->find_subtable (0, 0);
+ if (!subtable)
+ {
+ subtable = cmap->find_subtable (3, 0);
+ if (subtable) symbol = true;
+ }
+ /* Meh. */
+ if (!subtable) subtable = &OT::Null(OT::CmapSubtable);
+
+ /* UVS subtable. */
+ if (!subtable_uvs)
+ {
+ const OT::CmapSubtable *st = cmap->find_subtable (0, 5);
+ if (st && st->u.format == 14)
+ subtable_uvs = &st->u.format14;
+ }
+ /* Meh. */
+ if (!subtable_uvs) subtable_uvs = &OT::Null(OT::CmapSubtableFormat14);
+
+ this->uvs_table = subtable_uvs;
+
+ this->get_glyph_data = subtable;
+ if (unlikely (symbol))
+ this->get_glyph_func = get_glyph_from_symbol<OT::CmapSubtable>;
+ else
+ switch (subtable->u.format) {
+ /* Accelerate format 4 and format 12. */
+ default: this->get_glyph_func = get_glyph_from<OT::CmapSubtable>; break;
+ case 12: this->get_glyph_func = get_glyph_from<OT::CmapSubtableFormat12>; break;
+ case 4:
+ {
+ this->format4_accel.init (&subtable->u.format4);
+ this->get_glyph_data = &this->format4_accel;
+ this->get_glyph_func = this->format4_accel.get_glyph_func;
+ }
+ break;
+ }
+ }
+
+ inline void fini (void)
+ {
+ hb_blob_destroy (this->blob);
+ }
+
+ inline bool get_nominal_glyph (hb_codepoint_t unicode,
+ hb_codepoint_t *glyph) const
+ {
+ return this->get_glyph_func (this->get_glyph_data, unicode, glyph);
+ }
+
+ inline bool get_variation_glyph (hb_codepoint_t unicode,
+ hb_codepoint_t variation_selector,
+ hb_codepoint_t *glyph) const
+ {
+ switch (this->uvs_table->get_glyph_variant (unicode,
+ variation_selector,
+ glyph))
+ {
+ case OT::GLYPH_VARIANT_NOT_FOUND: return false;
+ case OT::GLYPH_VARIANT_FOUND: return true;
+ case OT::GLYPH_VARIANT_USE_DEFAULT: break;
+ }
+
+ return get_nominal_glyph (unicode, glyph);
+ }
+
+ protected:
+ typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj,
+ hb_codepoint_t codepoint,
+ hb_codepoint_t *glyph);
+
+ template <typename Type>
+ static inline bool get_glyph_from (const void *obj,
+ hb_codepoint_t codepoint,
+ hb_codepoint_t *glyph)
+ {
+ const Type *typed_obj = (const Type *) obj;
+ return typed_obj->get_glyph (codepoint, glyph);
+ }
+
+ template <typename Type>
+ static inline bool get_glyph_from_symbol (const void *obj,
+ hb_codepoint_t codepoint,
+ hb_codepoint_t *glyph)
+ {
+ const Type *typed_obj = (const Type *) obj;
+ if (likely (typed_obj->get_glyph (codepoint, glyph)))
+ return true;
+
+ if (codepoint <= 0x00FFu)
+ {
+ /* For symbol-encoded OpenType fonts, we duplicate the
+ * U+F000..F0FF range at U+0000..U+00FF. That's what
+ * Windows seems to do, and that's hinted about at:
+ * http://www.microsoft.com/typography/otspec/recom.htm
+ * under "Non-Standard (Symbol) Fonts". */
+ return typed_obj->get_glyph (0xF000u + codepoint, glyph);
+ }
+
+ return false;
+ }
+
+ private:
+ hb_cmap_get_glyph_func_t get_glyph_func;
+ const void *get_glyph_data;
+ OT::CmapSubtableFormat4::accelerator_t format4_accel;
+
+ const OT::CmapSubtableFormat14 *uvs_table;
+ hb_blob_t *blob;
+ };
+
+ protected:
+
inline const CmapSubtable *find_subtable (unsigned int platform_id,
unsigned int encoding_id) const
{
@@ -508,20 +648,13 @@ struct cmap
* unsorted subtable list. */
int result = encodingRecord./*bsearch*/lsearch (key);
if (result == -1 || !encodingRecord[result].subtable)
- return NULL;
+ return nullptr;
return &(this+encodingRecord[result].subtable);
}
- inline bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- likely (version == 0) &&
- encodingRecord.sanitize (c, this));
- }
-
- USHORT version; /* Table version number (0). */
+ protected:
+ UINT16 version; /* Table version number (0). */
SortedArrayOf<EncodingRecord>
encodingRecord; /* Encoding tables. */
public:
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc
index 5be055d344..9864064b11 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc
@@ -33,443 +33,20 @@
#include "hb-ot-cmap-table.hh"
#include "hb-ot-cbdt-table.hh"
#include "hb-ot-glyf-table.hh"
-#include "hb-ot-head-table.hh"
-#include "hb-ot-hhea-table.hh"
#include "hb-ot-hmtx-table.hh"
-#include "hb-ot-os2-table.hh"
-//#include "hb-ot-post-table.hh"
+#include "hb-ot-kern-table.hh"
+#include "hb-ot-post-table.hh"
-struct hb_ot_face_metrics_accelerator_t
-{
- unsigned int num_metrics;
- unsigned int num_advances;
- unsigned int default_advance;
- unsigned short ascender;
- unsigned short descender;
- unsigned short line_gap;
- bool has_font_extents;
-
- const OT::_mtx *table;
- hb_blob_t *blob;
-
- inline void init (hb_face_t *face,
- hb_tag_t _hea_tag,
- hb_tag_t _mtx_tag,
- hb_tag_t os2_tag,
- unsigned int default_advance = 0)
- {
- this->default_advance = default_advance ? default_advance : face->get_upem ();
-
- bool got_font_extents = false;
- if (os2_tag)
- {
- hb_blob_t *os2_blob = OT::Sanitizer<OT::os2>::sanitize (face->reference_table (os2_tag));
- const OT::os2 *os2 = OT::Sanitizer<OT::os2>::lock_instance (os2_blob);
-#define USE_TYPO_METRICS (1u<<7)
- if (0 != (os2->fsSelection & USE_TYPO_METRICS))
- {
- this->ascender = os2->sTypoAscender;
- this->descender = os2->sTypoDescender;
- this->line_gap = os2->sTypoLineGap;
- got_font_extents = (this->ascender | this->descender) != 0;
- }
- hb_blob_destroy (os2_blob);
- }
-
- hb_blob_t *_hea_blob = OT::Sanitizer<OT::_hea>::sanitize (face->reference_table (_hea_tag));
- const OT::_hea *_hea = OT::Sanitizer<OT::_hea>::lock_instance (_hea_blob);
- this->num_advances = _hea->numberOfLongMetrics;
- if (!got_font_extents)
- {
- this->ascender = _hea->ascender;
- this->descender = _hea->descender;
- this->line_gap = _hea->lineGap;
- got_font_extents = (this->ascender | this->descender) != 0;
- }
- hb_blob_destroy (_hea_blob);
-
- this->has_font_extents = got_font_extents;
-
- this->blob = OT::Sanitizer<OT::_mtx>::sanitize (face->reference_table (_mtx_tag));
-
- /* 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))
- 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.
- * Our get_advance() depends on that. */
- if (unlikely (!this->num_advances))
- {
- this->num_metrics = this->num_advances = 0;
- hb_blob_destroy (this->blob);
- this->blob = hb_blob_get_empty ();
- }
- this->table = OT::Sanitizer<OT::_mtx>::lock_instance (this->blob);
- }
-
- inline void fini (void)
- {
- hb_blob_destroy (this->blob);
- }
-
- inline unsigned int get_advance (hb_codepoint_t glyph) const
- {
- if (unlikely (glyph >= this->num_metrics))
- {
- /* If this->num_metrics is zero, it means we don't have the metrics table
- * for this direction: return default advance. Otherwise, it means that the
- * glyph index is out of bound: return zero. */
- if (this->num_metrics)
- return 0;
- else
- return this->default_advance;
- }
-
- if (glyph >= this->num_advances)
- glyph = this->num_advances - 1;
-
- return this->table->longMetric[glyph].advance;
- }
-};
-
-struct hb_ot_face_glyf_accelerator_t
-{
- bool short_offset;
- unsigned int num_glyphs;
- const OT::loca *loca;
- const OT::glyf *glyf;
- hb_blob_t *loca_blob;
- hb_blob_t *glyf_blob;
- unsigned int glyf_len;
-
- inline void init (hb_face_t *face)
- {
- hb_blob_t *head_blob = OT::Sanitizer<OT::head>::sanitize (face->reference_table (HB_OT_TAG_head));
- const OT::head *head = OT::Sanitizer<OT::head>::lock_instance (head_blob);
- if ((unsigned int) head->indexToLocFormat > 1 || head->glyphDataFormat != 0)
- {
- /* Unknown format. Leave num_glyphs=0, that takes care of disabling us. */
- hb_blob_destroy (head_blob);
- return;
- }
- this->short_offset = 0 == head->indexToLocFormat;
- hb_blob_destroy (head_blob);
-
- this->loca_blob = OT::Sanitizer<OT::loca>::sanitize (face->reference_table (HB_OT_TAG_loca));
- this->loca = OT::Sanitizer<OT::loca>::lock_instance (this->loca_blob);
- this->glyf_blob = OT::Sanitizer<OT::glyf>::sanitize (face->reference_table (HB_OT_TAG_glyf));
- this->glyf = OT::Sanitizer<OT::glyf>::lock_instance (this->glyf_blob);
-
- this->num_glyphs = MAX (1u, hb_blob_get_length (this->loca_blob) / (this->short_offset ? 2 : 4)) - 1;
- this->glyf_len = hb_blob_get_length (this->glyf_blob);
- }
-
- inline void fini (void)
- {
- hb_blob_destroy (this->loca_blob);
- hb_blob_destroy (this->glyf_blob);
- }
-
- inline bool get_extents (hb_codepoint_t glyph,
- hb_glyph_extents_t *extents) const
- {
- if (unlikely (glyph >= this->num_glyphs))
- return false;
-
- unsigned int start_offset, end_offset;
- if (this->short_offset)
- {
- start_offset = 2 * this->loca->u.shortsZ[glyph];
- end_offset = 2 * this->loca->u.shortsZ[glyph + 1];
- }
- else
- {
- start_offset = this->loca->u.longsZ[glyph];
- end_offset = this->loca->u.longsZ[glyph + 1];
- }
-
- if (start_offset > end_offset || end_offset > this->glyf_len)
- return false;
-
- if (end_offset - start_offset < OT::glyfGlyphHeader::static_size)
- return true; /* Empty glyph; zero extents. */
-
- const OT::glyfGlyphHeader &glyph_header = OT::StructAtOffset<OT::glyfGlyphHeader> (this->glyf, start_offset);
-
- extents->x_bearing = MIN (glyph_header.xMin, glyph_header.xMax);
- extents->y_bearing = MAX (glyph_header.yMin, glyph_header.yMax);
- extents->width = MAX (glyph_header.xMin, glyph_header.xMax) - extents->x_bearing;
- extents->height = MIN (glyph_header.yMin, glyph_header.yMax) - extents->y_bearing;
-
- return true;
- }
-};
-
-struct hb_ot_face_cbdt_accelerator_t
-{
- hb_blob_t *cblc_blob;
- hb_blob_t *cbdt_blob;
- const OT::CBLC *cblc;
- const OT::CBDT *cbdt;
-
- unsigned int cbdt_len;
- float upem;
-
- inline void init (hb_face_t *face)
- {
- upem = face->get_upem();
-
- cblc_blob = OT::Sanitizer<OT::CBLC>::sanitize (face->reference_table (HB_OT_TAG_CBLC));
- cbdt_blob = OT::Sanitizer<OT::CBDT>::sanitize (face->reference_table (HB_OT_TAG_CBDT));
- cbdt_len = hb_blob_get_length (cbdt_blob);
-
- if (hb_blob_get_length (cblc_blob) == 0) {
- cblc = NULL;
- cbdt = NULL;
- return; /* Not a bitmap font. */
- }
- cblc = OT::Sanitizer<OT::CBLC>::lock_instance (cblc_blob);
- cbdt = OT::Sanitizer<OT::CBDT>::lock_instance (cbdt_blob);
-
- }
-
- inline void fini (void)
- {
- hb_blob_destroy (this->cblc_blob);
- hb_blob_destroy (this->cbdt_blob);
- }
-
- inline bool get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
- {
- unsigned int x_ppem = upem, y_ppem = upem; /* TODO Use font ppem if available. */
-
- if (cblc == NULL)
- return false; // Not a color bitmap font.
-
- const OT::IndexSubtableRecord *subtable_record = this->cblc->find_table(glyph, &x_ppem, &y_ppem);
- if (subtable_record == NULL)
- return false;
-
- if (subtable_record->get_extents (extents))
- return true;
-
- unsigned int image_offset = 0, image_length = 0, image_format = 0;
- if (!subtable_record->get_image_data (glyph, &image_offset, &image_length, &image_format))
- return false;
-
- {
- /* TODO Move the following into CBDT struct when adding more formats. */
-
- if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length))
- return false;
-
- switch (image_format)
- {
- case 17: {
- if (unlikely (image_length < OT::GlyphBitmapDataFormat17::min_size))
- return false;
-
- const OT::GlyphBitmapDataFormat17& glyphFormat17 =
- OT::StructAtOffset<OT::GlyphBitmapDataFormat17> (this->cbdt, image_offset);
- glyphFormat17.glyphMetrics.get_extents (extents);
- }
- break;
- default:
- // TODO: Support other image formats.
- return false;
- }
- }
-
- /* Convert to the font units. */
- extents->x_bearing *= upem / (float) x_ppem;
- extents->y_bearing *= upem / (float) y_ppem;
- extents->width *= upem / (float) x_ppem;
- extents->height *= upem / (float) y_ppem;
-
- return true;
- }
-};
-
-typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj,
- hb_codepoint_t codepoint,
- hb_codepoint_t *glyph);
-
-template <typename Type>
-static inline bool get_glyph_from (const void *obj,
- hb_codepoint_t codepoint,
- hb_codepoint_t *glyph)
-{
- const Type *typed_obj = (const Type *) obj;
- return typed_obj->get_glyph (codepoint, glyph);
-}
-
-template <typename Type>
-static inline bool get_glyph_from_symbol (const void *obj,
- hb_codepoint_t codepoint,
- hb_codepoint_t *glyph)
-{
- const Type *typed_obj = (const Type *) obj;
- if (likely (typed_obj->get_glyph (codepoint, glyph)))
- return true;
-
- if (codepoint <= 0x00FFu)
- {
- /* For symbol-encoded OpenType fonts, we duplicate the
- * U+F000..F0FF range at U+0000..U+00FF. That's what
- * Windows seems to do, and that's hinted about at:
- * http://www.microsoft.com/typography/otspec/recom.htm
- * under "Non-Standard (Symbol) Fonts". */
- return typed_obj->get_glyph (0xF000u + codepoint, glyph);
- }
-
- return false;
-}
-
-struct hb_ot_face_cmap_accelerator_t
-{
- hb_cmap_get_glyph_func_t get_glyph_func;
- const void *get_glyph_data;
- OT::CmapSubtableFormat4::accelerator_t format4_accel;
-
- const OT::CmapSubtableFormat14 *uvs_table;
- hb_blob_t *blob;
-
- inline void init (hb_face_t *face)
- {
- this->blob = OT::Sanitizer<OT::cmap>::sanitize (face->reference_table (HB_OT_TAG_cmap));
- const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::lock_instance (this->blob);
- const OT::CmapSubtable *subtable = NULL;
- const OT::CmapSubtableFormat14 *subtable_uvs = NULL;
-
- bool symbol = false;
- /* 32-bit subtables. */
- if (!subtable) subtable = cmap->find_subtable (3, 10);
- if (!subtable) subtable = cmap->find_subtable (0, 6);
- if (!subtable) subtable = cmap->find_subtable (0, 4);
- /* 16-bit subtables. */
- if (!subtable) subtable = cmap->find_subtable (3, 1);
- if (!subtable) subtable = cmap->find_subtable (0, 3);
- if (!subtable) subtable = cmap->find_subtable (0, 2);
- if (!subtable) subtable = cmap->find_subtable (0, 1);
- if (!subtable) subtable = cmap->find_subtable (0, 0);
- if (!subtable)
- {
- subtable = cmap->find_subtable (3, 0);
- if (subtable) symbol = true;
- }
- /* Meh. */
- if (!subtable) subtable = &OT::Null(OT::CmapSubtable);
-
- /* UVS subtable. */
- if (!subtable_uvs)
- {
- const OT::CmapSubtable *st = cmap->find_subtable (0, 5);
- if (st && st->u.format == 14)
- subtable_uvs = &st->u.format14;
- }
- /* Meh. */
- if (!subtable_uvs) subtable_uvs = &OT::Null(OT::CmapSubtableFormat14);
-
- this->uvs_table = subtable_uvs;
-
- this->get_glyph_data = subtable;
- if (unlikely (symbol))
- this->get_glyph_func = get_glyph_from_symbol<OT::CmapSubtable>;
- else
- switch (subtable->u.format) {
- /* Accelerate format 4 and format 12. */
- default: this->get_glyph_func = get_glyph_from<OT::CmapSubtable>; break;
- case 12: this->get_glyph_func = get_glyph_from<OT::CmapSubtableFormat12>; break;
- case 4:
- {
- this->format4_accel.init (&subtable->u.format4);
- this->get_glyph_data = &this->format4_accel;
- this->get_glyph_func = this->format4_accel.get_glyph_func;
- }
- break;
- }
- }
-
- inline void fini (void)
- {
- hb_blob_destroy (this->blob);
- }
-
- inline bool get_nominal_glyph (hb_codepoint_t unicode,
- hb_codepoint_t *glyph) const
- {
- return this->get_glyph_func (this->get_glyph_data, unicode, glyph);
- }
-
- inline bool get_variation_glyph (hb_codepoint_t unicode,
- hb_codepoint_t variation_selector,
- hb_codepoint_t *glyph) const
- {
- switch (this->uvs_table->get_glyph_variant (unicode,
- variation_selector,
- glyph))
- {
- case OT::GLYPH_VARIANT_NOT_FOUND: return false;
- case OT::GLYPH_VARIANT_FOUND: return true;
- case OT::GLYPH_VARIANT_USE_DEFAULT: break;
- }
-
- return get_nominal_glyph (unicode, glyph);
- }
-};
-
-template <typename T>
-struct hb_lazy_loader_t
-{
- inline void init (hb_face_t *face_)
- {
- face = face_;
- instance = NULL;
- }
-
- inline void fini (void)
- {
- if (instance && instance != &OT::Null(T))
- {
- instance->fini();
- free (instance);
- }
- }
-
- inline const T* operator-> (void) const
- {
- retry:
- T *p = (T *) hb_atomic_ptr_get (&instance);
- if (unlikely (!p))
- {
- p = (T *) calloc (1, sizeof (T));
- if (unlikely (!p))
- return &OT::Null(T);
- p->init (face);
- if (unlikely (!hb_atomic_ptr_cmpexch (const_cast<T **>(&instance), NULL, p)))
- {
- p->fini ();
- goto retry;
- }
- }
- return p;
- }
-
- private:
- hb_face_t *face;
- T *instance;
-};
-
struct hb_ot_font_t
{
- hb_ot_face_cmap_accelerator_t cmap;
- hb_ot_face_metrics_accelerator_t h_metrics;
- hb_ot_face_metrics_accelerator_t v_metrics;
- hb_lazy_loader_t<hb_ot_face_glyf_accelerator_t> glyf;
- hb_lazy_loader_t<hb_ot_face_cbdt_accelerator_t> cbdt;
+ OT::cmap::accelerator_t cmap;
+ OT::hmtx::accelerator_t h_metrics;
+ OT::vmtx::accelerator_t v_metrics;
+ OT::hb_lazy_loader_t<OT::glyf::accelerator_t> glyf;
+ OT::hb_lazy_loader_t<OT::CBDT::accelerator_t> cbdt;
+ OT::hb_lazy_loader_t<OT::post::accelerator_t> post;
+ OT::hb_lazy_loader_t<OT::kern::accelerator_t> kern;
};
@@ -479,26 +56,31 @@ _hb_ot_font_create (hb_face_t *face)
hb_ot_font_t *ot_font = (hb_ot_font_t *) calloc (1, sizeof (hb_ot_font_t));
if (unlikely (!ot_font))
- return NULL;
+ return nullptr;
ot_font->cmap.init (face);
- ot_font->h_metrics.init (face, HB_OT_TAG_hhea, HB_OT_TAG_hmtx, HB_OT_TAG_os2);
- ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, HB_TAG_NONE,
- ot_font->h_metrics.ascender - ot_font->h_metrics.descender); /* TODO Can we do this lazily? */
+ ot_font->h_metrics.init (face);
+ ot_font->v_metrics.init (face, ot_font->h_metrics.ascender - ot_font->h_metrics.descender); /* TODO Can we do this lazily? */
ot_font->glyf.init (face);
ot_font->cbdt.init (face);
+ ot_font->post.init (face);
+ ot_font->kern.init (face);
return ot_font;
}
static void
-_hb_ot_font_destroy (hb_ot_font_t *ot_font)
+_hb_ot_font_destroy (void *data)
{
+ hb_ot_font_t *ot_font = (hb_ot_font_t *) data;
+
ot_font->cmap.fini ();
ot_font->h_metrics.fini ();
ot_font->v_metrics.fini ();
ot_font->glyf.fini ();
ot_font->cbdt.fini ();
+ ot_font->post.fini ();
+ ot_font->kern.fini ();
free (ot_font);
}
@@ -529,23 +111,34 @@ hb_ot_get_variation_glyph (hb_font_t *font HB_UNUSED,
}
static hb_position_t
-hb_ot_get_glyph_h_advance (hb_font_t *font HB_UNUSED,
+hb_ot_get_glyph_h_advance (hb_font_t *font,
void *font_data,
hb_codepoint_t glyph,
void *user_data HB_UNUSED)
{
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
- return font->em_scale_x (ot_font->h_metrics.get_advance (glyph));
+ return font->em_scale_x (ot_font->h_metrics.get_advance (glyph, font));
}
static hb_position_t
-hb_ot_get_glyph_v_advance (hb_font_t *font HB_UNUSED,
+hb_ot_get_glyph_v_advance (hb_font_t *font,
void *font_data,
hb_codepoint_t glyph,
void *user_data HB_UNUSED)
{
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
- return font->em_scale_y (-(int) ot_font->v_metrics.get_advance (glyph));
+ return font->em_scale_y (-(int) ot_font->v_metrics.get_advance (glyph, font));
+}
+
+static hb_position_t
+hb_ot_get_glyph_h_kerning (hb_font_t *font,
+ void *font_data,
+ hb_codepoint_t left_glyph,
+ hb_codepoint_t right_glyph,
+ void *user_data HB_UNUSED)
+{
+ const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
+ return font->em_scale_x (ot_font->kern->get_h_kerning (left_glyph, right_glyph));
}
static hb_bool_t
@@ -559,6 +152,7 @@ hb_ot_get_glyph_extents (hb_font_t *font HB_UNUSED,
bool ret = ot_font->glyf->get_extents (glyph, extents);
if (!ret)
ret = ot_font->cbdt->get_extents (glyph, extents);
+ // TODO Hook up side-bearings variations.
extents->x_bearing = font->em_scale_x (extents->x_bearing);
extents->y_bearing = font->em_scale_y (extents->y_bearing);
extents->width = font->em_scale_x (extents->width);
@@ -567,6 +161,28 @@ hb_ot_get_glyph_extents (hb_font_t *font HB_UNUSED,
}
static hb_bool_t
+hb_ot_get_glyph_name (hb_font_t *font HB_UNUSED,
+ void *font_data,
+ hb_codepoint_t glyph,
+ char *name, unsigned int size,
+ void *user_data HB_UNUSED)
+{
+ const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
+ return ot_font->post->get_glyph_name (glyph, name, size);
+}
+
+static hb_bool_t
+hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED,
+ void *font_data,
+ const char *name, int len,
+ hb_codepoint_t *glyph,
+ void *user_data HB_UNUSED)
+{
+ const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
+ return ot_font->post->get_glyph_from_name (name, len, glyph);
+}
+
+static hb_bool_t
hb_ot_get_font_h_extents (hb_font_t *font HB_UNUSED,
void *font_data,
hb_font_extents_t *metrics,
@@ -576,6 +192,7 @@ hb_ot_get_font_h_extents (hb_font_t *font HB_UNUSED,
metrics->ascender = font->em_scale_y (ot_font->h_metrics.ascender);
metrics->descender = font->em_scale_y (ot_font->h_metrics.descender);
metrics->line_gap = font->em_scale_y (ot_font->h_metrics.line_gap);
+ // TODO Hook up variations.
return ot_font->h_metrics.has_font_extents;
}
@@ -589,10 +206,11 @@ hb_ot_get_font_v_extents (hb_font_t *font HB_UNUSED,
metrics->ascender = font->em_scale_x (ot_font->v_metrics.ascender);
metrics->descender = font->em_scale_x (ot_font->v_metrics.descender);
metrics->line_gap = font->em_scale_x (ot_font->v_metrics.line_gap);
+ // TODO Hook up variations.
return ot_font->v_metrics.has_font_extents;
}
-static hb_font_funcs_t *static_ot_funcs = NULL;
+static hb_font_funcs_t *static_ot_funcs = nullptr;
#ifdef HB_USE_ATEXIT
static
@@ -612,24 +230,24 @@ retry:
{
funcs = hb_font_funcs_create ();
- hb_font_funcs_set_font_h_extents_func (funcs, hb_ot_get_font_h_extents, NULL, NULL);
- hb_font_funcs_set_font_v_extents_func (funcs, hb_ot_get_font_v_extents, NULL, NULL);
- hb_font_funcs_set_nominal_glyph_func (funcs, hb_ot_get_nominal_glyph, NULL, NULL);
- hb_font_funcs_set_variation_glyph_func (funcs, hb_ot_get_variation_glyph, NULL, NULL);
- hb_font_funcs_set_glyph_h_advance_func (funcs, hb_ot_get_glyph_h_advance, NULL, NULL);
- hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ot_get_glyph_v_advance, NULL, NULL);
- //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ot_get_glyph_h_origin, NULL, NULL);
- //hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, NULL, NULL);
- //hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ot_get_glyph_h_kerning, NULL, NULL); TODO
- //hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ot_get_glyph_v_kerning, NULL, NULL);
- hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, NULL, NULL);
- //hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, NULL, NULL); TODO
- //hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, NULL, NULL); TODO
- //hb_font_funcs_set_glyph_from_name_func (funcs, hb_ot_get_glyph_from_name, NULL, NULL); TODO
+ hb_font_funcs_set_font_h_extents_func (funcs, hb_ot_get_font_h_extents, nullptr, nullptr);
+ hb_font_funcs_set_font_v_extents_func (funcs, hb_ot_get_font_v_extents, nullptr, nullptr);
+ hb_font_funcs_set_nominal_glyph_func (funcs, hb_ot_get_nominal_glyph, nullptr, nullptr);
+ hb_font_funcs_set_variation_glyph_func (funcs, hb_ot_get_variation_glyph, nullptr, nullptr);
+ hb_font_funcs_set_glyph_h_advance_func (funcs, hb_ot_get_glyph_h_advance, nullptr, nullptr);
+ hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ot_get_glyph_v_advance, nullptr, nullptr);
+ //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ot_get_glyph_h_origin, nullptr, nullptr);
+ //hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, nullptr, nullptr);
+ hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ot_get_glyph_h_kerning, nullptr, nullptr);
+ //hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ot_get_glyph_v_kerning, nullptr, nullptr);
+ hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, nullptr, nullptr);
+ //hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, nullptr, nullptr);
+ hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, nullptr, nullptr);
+ hb_font_funcs_set_glyph_from_name_func (funcs, hb_ot_get_glyph_from_name, nullptr, nullptr);
hb_font_funcs_make_immutable (funcs);
- if (!hb_atomic_ptr_cmpexch (&static_ot_funcs, NULL, funcs)) {
+ if (!hb_atomic_ptr_cmpexch (&static_ot_funcs, nullptr, funcs)) {
hb_font_funcs_destroy (funcs);
goto retry;
}
@@ -658,5 +276,5 @@ hb_ot_font_set_funcs (hb_font_t *font)
hb_font_set_funcs (font,
_hb_ot_get_font_funcs (),
ot_font,
- (hb_destroy_func_t) _hb_ot_font_destroy);
+ _hb_ot_font_destroy);
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh
index dc7aa8469a..88d3850b6e 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh
@@ -28,6 +28,7 @@
#define HB_OT_GLYF_TABLE_HH
#include "hb-open-type-private.hh"
+#include "hb-ot-head-table.hh"
namespace OT {
@@ -42,6 +43,8 @@ namespace OT {
struct loca
{
+ friend struct glyf;
+
static const hb_tag_t tableTag = HB_OT_TAG_loca;
inline bool sanitize (hb_sanitize_context_t *c) const
@@ -50,12 +53,9 @@ struct loca
return_trace (true);
}
- public:
- union {
- USHORT shortsZ[VAR]; /* Location offset divided by 2. */
- ULONG longsZ[VAR]; /* Location offset. */
- } u;
- DEFINE_SIZE_ARRAY (0, u.longsZ);
+ protected:
+ UINT8 dataX[VAR]; /* Location data. */
+ DEFINE_SIZE_ARRAY (0, dataX);
};
@@ -78,26 +78,102 @@ struct glyf
return_trace (true);
}
- public:
- BYTE dataX[VAR]; /* Glyphs data. */
+ struct GlyphHeader
+ {
+ INT16 numberOfContours; /* If the number of contours is
+ * greater than or equal to zero,
+ * this is a simple glyph; if negative,
+ * this is a composite glyph. */
+ FWORD xMin; /* Minimum x for coordinate data. */
+ FWORD yMin; /* Minimum y for coordinate data. */
+ FWORD xMax; /* Maximum x for coordinate data. */
+ FWORD yMax; /* Maximum y for coordinate data. */
+
+ DEFINE_SIZE_STATIC (10);
+ };
+
+ struct accelerator_t
+ {
+ inline void init (hb_face_t *face)
+ {
+ hb_blob_t *head_blob = Sanitizer<head>::sanitize (face->reference_table (HB_OT_TAG_head));
+ const head *head_table = Sanitizer<head>::lock_instance (head_blob);
+ if ((unsigned int) head_table->indexToLocFormat > 1 || head_table->glyphDataFormat != 0)
+ {
+ /* Unknown format. Leave num_glyphs=0, that takes care of disabling us. */
+ hb_blob_destroy (head_blob);
+ return;
+ }
+ short_offset = 0 == head_table->indexToLocFormat;
+ hb_blob_destroy (head_blob);
+
+ loca_blob = Sanitizer<loca>::sanitize (face->reference_table (HB_OT_TAG_loca));
+ loca_table = Sanitizer<loca>::lock_instance (loca_blob);
+ glyf_blob = Sanitizer<glyf>::sanitize (face->reference_table (HB_OT_TAG_glyf));
+ glyf_table = Sanitizer<glyf>::lock_instance (glyf_blob);
+
+ num_glyphs = MAX (1u, hb_blob_get_length (loca_blob) / (short_offset ? 2 : 4)) - 1;
+ glyf_len = hb_blob_get_length (glyf_blob);
+ }
+
+ inline void fini (void)
+ {
+ hb_blob_destroy (loca_blob);
+ hb_blob_destroy (glyf_blob);
+ }
+
+ inline bool get_extents (hb_codepoint_t glyph,
+ hb_glyph_extents_t *extents) const
+ {
+ if (unlikely (glyph >= num_glyphs))
+ return false;
+
+ unsigned int start_offset, end_offset;
+ if (short_offset)
+ {
+ const UINT16 *offsets = (const UINT16 *) loca_table->dataX;
+ start_offset = 2 * offsets[glyph];
+ end_offset = 2 * offsets[glyph + 1];
+ }
+ else
+ {
+ const UINT32 *offsets = (const UINT32 *) loca_table->dataX;
+ start_offset = offsets[glyph];
+ end_offset = offsets[glyph + 1];
+ }
+
+ if (start_offset > end_offset || end_offset > glyf_len)
+ return false;
+
+ if (end_offset - start_offset < GlyphHeader::static_size)
+ return true; /* Empty glyph; zero extents. */
+
+ const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyf_table, start_offset);
+
+ extents->x_bearing = MIN (glyph_header.xMin, glyph_header.xMax);
+ extents->y_bearing = MAX (glyph_header.yMin, glyph_header.yMax);
+ extents->width = MAX (glyph_header.xMin, glyph_header.xMax) - extents->x_bearing;
+ extents->height = MIN (glyph_header.yMin, glyph_header.yMax) - extents->y_bearing;
+
+ return true;
+ }
+
+ private:
+ bool short_offset;
+ unsigned int num_glyphs;
+ const loca *loca_table;
+ const glyf *glyf_table;
+ hb_blob_t *loca_blob;
+ hb_blob_t *glyf_blob;
+ unsigned int glyf_len;
+ };
+
+ protected:
+ UINT8 dataX[VAR]; /* Glyphs data. */
DEFINE_SIZE_ARRAY (0, dataX);
};
-struct glyfGlyphHeader
-{
- SHORT numberOfContours; /* If the number of contours is
- * greater than or equal to zero,
- * this is a simple glyph; if negative,
- * this is a composite glyph. */
- FWORD xMin; /* Minimum x for coordinate data. */
- FWORD yMin; /* Minimum y for coordinate data. */
- FWORD xMax; /* Maximum x for coordinate data. */
- FWORD yMax; /* Maximum y for coordinate data. */
-
- DEFINE_SIZE_STATIC (10);
-};
-
} /* namespace OT */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh
index 9c3e51eb08..dd4349ef85 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh
@@ -64,11 +64,11 @@ struct head
FixedVersion<>version; /* Version of the head table--currently
* 0x00010000u for version 1.0. */
FixedVersion<>fontRevision; /* Set by font manufacturer. */
- ULONG checkSumAdjustment; /* To compute: set it to 0, sum the
- * entire font as ULONG, then store
+ UINT32 checkSumAdjustment; /* To compute: set it to 0, sum the
+ * entire font as UINT32, then store
* 0xB1B0AFBAu - sum. */
- ULONG magicNumber; /* Set to 0x5F0F3CF5u. */
- USHORT flags; /* Bit 0: Baseline for font at y=0;
+ UINT32 magicNumber; /* Set to 0x5F0F3CF5u. */
+ UINT16 flags; /* Bit 0: Baseline for font at y=0;
* Bit 1: Left sidebearing point at x=0;
* Bit 2: Instructions may depend on point size;
* Bit 3: Force ppem to integer values for all
@@ -114,18 +114,18 @@ struct head
* encoded in the cmap subtables represent proper
* support for those code points.
* Bit 15: Reserved, set to 0. */
- USHORT unitsPerEm; /* Valid range is from 16 to 16384. This value
+ UINT16 unitsPerEm; /* Valid range is from 16 to 16384. This value
* should be a power of 2 for fonts that have
* TrueType outlines. */
LONGDATETIME created; /* Number of seconds since 12:00 midnight,
January 1, 1904. 64-bit integer */
LONGDATETIME modified; /* Number of seconds since 12:00 midnight,
January 1, 1904. 64-bit integer */
- SHORT xMin; /* For all glyph bounding boxes. */
- SHORT yMin; /* For all glyph bounding boxes. */
- SHORT xMax; /* For all glyph bounding boxes. */
- SHORT yMax; /* For all glyph bounding boxes. */
- USHORT macStyle; /* Bit 0: Bold (if set to 1);
+ INT16 xMin; /* For all glyph bounding boxes. */
+ INT16 yMin; /* For all glyph bounding boxes. */
+ INT16 xMax; /* For all glyph bounding boxes. */
+ INT16 yMax; /* For all glyph bounding boxes. */
+ UINT16 macStyle; /* Bit 0: Bold (if set to 1);
* Bit 1: Italic (if set to 1)
* Bit 2: Underline (if set to 1)
* Bit 3: Outline (if set to 1)
@@ -133,16 +133,16 @@ struct head
* Bit 5: Condensed (if set to 1)
* Bit 6: Extended (if set to 1)
* Bits 7-15: Reserved (set to 0). */
- USHORT lowestRecPPEM; /* Smallest readable size in pixels. */
- SHORT fontDirectionHint; /* Deprecated (Set to 2).
+ UINT16 lowestRecPPEM; /* Smallest readable size in pixels. */
+ INT16 fontDirectionHint; /* Deprecated (Set to 2).
* 0: Fully mixed directional glyphs;
* 1: Only strongly left to right;
* 2: Like 1 but also contains neutrals;
* -1: Only strongly right to left;
* -2: Like -1 but also contains neutrals. */
public:
- SHORT indexToLocFormat; /* 0 for short offsets, 1 for long. */
- SHORT glyphDataFormat; /* 0 for current format. */
+ INT16 indexToLocFormat; /* 0 for short offsets, 1 for long. */
+ INT16 glyphDataFormat; /* 0 for current format. */
DEFINE_SIZE_STATIC (54);
};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh
index c8e9536cf1..dca014148e 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh
@@ -44,11 +44,6 @@ namespace OT {
struct _hea
{
- static const hb_tag_t tableTag = HB_TAG('_','h','e','a');
-
- static const hb_tag_t hheaTag = HB_OT_TAG_hhea;
- static const hb_tag_t vheaTag = HB_OT_TAG_vhea;
-
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -69,21 +64,21 @@ struct _hea
* (xMax - xMin)) for horizontal. */
FWORD maxExtent; /* horizontal: Max(lsb + (xMax - xMin)),
* vertical: minLeadingBearing+(yMax-yMin). */
- SHORT caretSlopeRise; /* Used to calculate the slope of the
+ INT16 caretSlopeRise; /* Used to calculate the slope of the
* cursor (rise/run); 1 for vertical caret,
* 0 for horizontal.*/
- SHORT caretSlopeRun; /* 0 for vertical caret, 1 for horizontal. */
- SHORT caretOffset; /* The amount by which a slanted
+ INT16 caretSlopeRun; /* 0 for vertical caret, 1 for horizontal. */
+ INT16 caretOffset; /* The amount by which a slanted
* highlight on a glyph needs
* to be shifted to produce the
* best appearance. Set to 0 for
* non-slanted fonts. */
- SHORT reserved1; /* Set to 0. */
- SHORT reserved2; /* Set to 0. */
- SHORT reserved3; /* Set to 0. */
- SHORT reserved4; /* Set to 0. */
- SHORT metricDataFormat; /* 0 for current format. */
- USHORT numberOfLongMetrics; /* Number of LongMetric entries in metric
+ INT16 reserved1; /* Set to 0. */
+ INT16 reserved2; /* Set to 0. */
+ INT16 reserved3; /* Set to 0. */
+ INT16 reserved4; /* Set to 0. */
+ INT16 metricDataFormat; /* 0 for current format. */
+ UINT16 numberOfLongMetrics; /* Number of LongMetric entries in metric
* table. */
public:
DEFINE_SIZE_STATIC (36);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh
index a9606b3d27..e710aee42e 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh
@@ -28,6 +28,9 @@
#define HB_OT_HMTX_TABLE_HH
#include "hb-open-type-private.hh"
+#include "hb-ot-hhea-table.hh"
+#include "hb-ot-os2-table.hh"
+#include "hb-ot-var-hvar-table.hh"
namespace OT {
@@ -50,13 +53,9 @@ struct LongMetric
DEFINE_SIZE_STATIC (4);
};
-struct _mtx
+template <typename T>
+struct hmtxvmtx
{
- static const hb_tag_t tableTag = HB_TAG('_','m','t','x');
-
- static const hb_tag_t hmtxTag = HB_OT_TAG_hmtx;
- static const hb_tag_t vmtxTag = HB_OT_TAG_vmtx;
-
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -65,7 +64,107 @@ struct _mtx
return_trace (true);
}
- public:
+ struct accelerator_t
+ {
+ inline void init (hb_face_t *face,
+ unsigned int default_advance_ = 0)
+ {
+ default_advance = default_advance_ ? default_advance_ : face->get_upem ();
+
+ bool got_font_extents = false;
+ if (T::os2Tag)
+ {
+ hb_blob_t *os2_blob = Sanitizer<os2>::sanitize (face->reference_table (T::os2Tag));
+ const os2 *os2_table = Sanitizer<os2>::lock_instance (os2_blob);
+#define USE_TYPO_METRICS (1u<<7)
+ if (0 != (os2_table->fsSelection & USE_TYPO_METRICS))
+ {
+ ascender = os2_table->sTypoAscender;
+ descender = os2_table->sTypoDescender;
+ line_gap = os2_table->sTypoLineGap;
+ got_font_extents = (ascender | descender) != 0;
+ }
+ hb_blob_destroy (os2_blob);
+ }
+
+ hb_blob_t *_hea_blob = Sanitizer<_hea>::sanitize (face->reference_table (T::headerTag));
+ const _hea *_hea_table = Sanitizer<_hea>::lock_instance (_hea_blob);
+ num_advances = _hea_table->numberOfLongMetrics;
+ if (!got_font_extents)
+ {
+ ascender = _hea_table->ascender;
+ descender = _hea_table->descender;
+ line_gap = _hea_table->lineGap;
+ got_font_extents = (ascender | descender) != 0;
+ }
+ hb_blob_destroy (_hea_blob);
+
+ has_font_extents = got_font_extents;
+
+ blob = Sanitizer<hmtxvmtx>::sanitize (face->reference_table (T::tableTag));
+
+ /* Cap num_metrics() and num_advances() based on table length. */
+ unsigned int len = hb_blob_get_length (blob);
+ if (unlikely (num_advances * 4 > len))
+ num_advances = len / 4;
+ num_metrics = num_advances + (len - 4 * num_advances) / 2;
+
+ /* We MUST set num_metrics to zero if num_advances is zero.
+ * Our get_advance() depends on that. */
+ if (unlikely (!num_advances))
+ {
+ num_metrics = num_advances = 0;
+ hb_blob_destroy (blob);
+ blob = hb_blob_get_empty ();
+ }
+ table = Sanitizer<hmtxvmtx>::lock_instance (blob);
+
+ var_blob = Sanitizer<HVARVVAR>::sanitize (face->reference_table (T::variationsTag));
+ var_table = Sanitizer<HVARVVAR>::lock_instance (var_blob);
+ }
+
+ inline void fini (void)
+ {
+ hb_blob_destroy (blob);
+ hb_blob_destroy (var_blob);
+ }
+
+ inline unsigned int get_advance (hb_codepoint_t glyph,
+ hb_font_t *font) const
+ {
+ if (unlikely (glyph >= num_metrics))
+ {
+ /* If num_metrics is zero, it means we don't have the metrics table
+ * for this direction: return default advance. Otherwise, it means that the
+ * glyph index is out of bound: return zero. */
+ if (num_metrics)
+ return 0;
+ else
+ return default_advance;
+ }
+
+ return table->longMetric[MIN (glyph, (uint32_t) num_advances - 1)].advance
+ + var_table->get_advance_var (glyph, font->coords, font->num_coords); // TODO Optimize?!
+ }
+
+ public:
+ bool has_font_extents;
+ unsigned short ascender;
+ unsigned short descender;
+ unsigned short line_gap;
+
+ private:
+ unsigned int num_metrics;
+ unsigned int num_advances;
+ unsigned int default_advance;
+
+ const hmtxvmtx *table;
+ hb_blob_t *blob;
+ const HVARVVAR *var_table;
+ hb_blob_t *var_blob;
+ };
+
+ protected:
LongMetric longMetric[VAR]; /* Paired advance width and leading
* bearing values for each glyph. The
* value numOfHMetrics comes from
@@ -91,11 +190,17 @@ struct _mtx
DEFINE_SIZE_ARRAY2 (0, longMetric, leadingBearingX);
};
-struct hmtx : _mtx {
+struct hmtx : hmtxvmtx<hmtx> {
static const hb_tag_t tableTag = HB_OT_TAG_hmtx;
+ static const hb_tag_t headerTag = HB_OT_TAG_hhea;
+ static const hb_tag_t variationsTag = HB_OT_TAG_HVAR;
+ static const hb_tag_t os2Tag = HB_OT_TAG_os2;
};
-struct vmtx : _mtx {
+struct vmtx : hmtxvmtx<vmtx> {
static const hb_tag_t tableTag = HB_OT_TAG_vmtx;
+ static const hb_tag_t headerTag = HB_OT_TAG_vhea;
+ static const hb_tag_t variationsTag = HB_OT_TAG_VVAR;
+ static const hb_tag_t os2Tag = HB_TAG_NONE;
};
} /* namespace OT */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-kern-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-kern-table.hh
new file mode 100644
index 0000000000..e07faca63f
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-kern-table.hh
@@ -0,0 +1,394 @@
+/*
+ * 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_KERN_TABLE_HH
+#define HB_OT_KERN_TABLE_HH
+
+#include "hb-open-type-private.hh"
+
+namespace OT {
+
+
+/*
+ * kern -- Kerning
+ */
+
+#define HB_OT_TAG_kern HB_TAG('k','e','r','n')
+
+struct hb_glyph_pair_t
+{
+ hb_codepoint_t left;
+ hb_codepoint_t right;
+};
+
+struct KernPair
+{
+ inline int get_kerning (void) const
+ { return value; }
+
+ inline int cmp (const hb_glyph_pair_t &o) const
+ {
+ int ret = left.cmp (o.left);
+ if (ret) return ret;
+ return right.cmp (o.right);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this));
+ }
+
+ protected:
+ GlyphID left;
+ GlyphID right;
+ FWORD value;
+ public:
+ DEFINE_SIZE_STATIC (6);
+};
+
+struct KernSubTableFormat0
+{
+ inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
+ {
+ hb_glyph_pair_t pair = {left, right};
+ int i = pairs.bsearch (pair);
+ if (i == -1)
+ return 0;
+ return pairs[i].get_kerning ();
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (pairs.sanitize (c));
+ }
+
+ protected:
+ BinSearchArrayOf<KernPair> pairs; /* Array of kerning pairs. */
+ public:
+ DEFINE_SIZE_ARRAY (8, pairs);
+};
+
+struct KernClassTable
+{
+ inline unsigned int get_class (hb_codepoint_t g) const { return classes[g - firstGlyph]; }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (firstGlyph.sanitize (c) && classes.sanitize (c));
+ }
+
+ protected:
+ UINT16 firstGlyph; /* First glyph in class range. */
+ ArrayOf<UINT16> classes; /* Glyph classes. */
+ public:
+ DEFINE_SIZE_ARRAY (4, classes);
+};
+
+struct KernSubTableFormat2
+{
+ inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
+ {
+ unsigned int l = (this+leftClassTable).get_class (left);
+ unsigned int r = (this+leftClassTable).get_class (left);
+ unsigned int offset = l * rowWidth + r * sizeof (FWORD);
+ const FWORD *arr = &(this+array);
+ if (unlikely ((const void *) arr < (const void *) this || (const void *) arr >= (const void *) end))
+ return 0;
+ const FWORD *v = &StructAtOffset<FWORD> (arr, offset);
+ if (unlikely ((const void *) v < (const void *) arr || (const void *) (v + 1) > (const void *) end))
+ return 0;
+ return *v;
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (rowWidth.sanitize (c) &&
+ leftClassTable.sanitize (c, this) &&
+ rightClassTable.sanitize (c, this) &&
+ array.sanitize (c, this));
+ }
+
+ protected:
+ UINT16 rowWidth; /* The width, in bytes, of a row in the table. */
+ OffsetTo<KernClassTable>
+ leftClassTable; /* Offset from beginning of this subtable to
+ * left-hand class table. */
+ OffsetTo<KernClassTable>
+ rightClassTable;/* Offset from beginning of this subtable to
+ * right-hand class table. */
+ OffsetTo<FWORD>
+ array; /* Offset from beginning of this subtable to
+ * the start of the kerning array. */
+ public:
+ DEFINE_SIZE_MIN (8);
+};
+
+struct KernSubTable
+{
+ inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end, unsigned int format) const
+ {
+ switch (format) {
+ case 0: return u.format0.get_kerning (left, right);
+ case 2: return u.format2.get_kerning (left, right, end);
+ default:return 0;
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c, unsigned int format) const
+ {
+ TRACE_SANITIZE (this);
+ switch (format) {
+ case 0: return_trace (u.format0.sanitize (c));
+ case 2: return_trace (u.format2.sanitize (c));
+ default:return_trace (true);
+ }
+ }
+
+ protected:
+ union {
+ KernSubTableFormat0 format0;
+ KernSubTableFormat2 format2;
+ } u;
+ public:
+ DEFINE_SIZE_MIN (0);
+};
+
+
+template <typename T>
+struct KernSubTableWrapper
+{
+ /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
+ inline const T* thiz (void) const { return static_cast<const T *> (this); }
+
+ inline bool is_horizontal (void) const
+ { return (thiz()->coverage & T::COVERAGE_CHECK_FLAGS) == T::COVERAGE_CHECK_HORIZONTAL; }
+
+ inline bool is_override (void) const
+ { return bool (thiz()->coverage & T::COVERAGE_OVERRIDE_FLAG); }
+
+ inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
+ { return thiz()->subtable.get_kerning (left, right, end, thiz()->format); }
+
+ inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
+ { return is_horizontal () ? get_kerning (left, right, end) : 0; }
+
+ inline unsigned int get_size (void) const { return thiz()->length; }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (thiz()) &&
+ thiz()->length >= thiz()->min_size &&
+ c->check_array (thiz(), 1, thiz()->length) &&
+ thiz()->subtable.sanitize (c, thiz()->format));
+ }
+};
+
+template <typename T>
+struct KernTable
+{
+ /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
+ inline const T* thiz (void) const { return static_cast<const T *> (this); }
+
+ inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right, unsigned int table_length) const
+ {
+ int v = 0;
+ const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (thiz()->data);
+ unsigned int count = thiz()->nTables;
+ for (unsigned int i = 0; i < count; i++)
+ {
+ if (st->is_override ())
+ v = 0;
+ v += st->get_h_kerning (left, right, table_length + (const char *) this);
+ st = &StructAfter<typename T::SubTableWrapper> (*st);
+ }
+ return v;
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (unlikely (!c->check_struct (thiz()) ||
+ thiz()->version != T::VERSION))
+ return_trace (false);
+
+ const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (thiz()->data);
+ unsigned int count = thiz()->nTables;
+ for (unsigned int i = 0; i < count; i++)
+ {
+ if (unlikely (!st->sanitize (c)))
+ return_trace (false);
+ st = &StructAfter<typename T::SubTableWrapper> (*st);
+ }
+
+ return_trace (true);
+ }
+};
+
+struct KernOT : KernTable<KernOT>
+{
+ friend struct KernTable<KernOT>;
+
+ static const uint16_t VERSION = 0x0000u;
+
+ struct SubTableWrapper : KernSubTableWrapper<SubTableWrapper>
+ {
+ friend struct KernSubTableWrapper<SubTableWrapper>;
+
+ enum coverage_flags_t {
+ COVERAGE_DIRECTION_FLAG = 0x01u,
+ COVERAGE_MINIMUM_FLAG = 0x02u,
+ COVERAGE_CROSSSTREAM_FLAG = 0x04u,
+ COVERAGE_OVERRIDE_FLAG = 0x08u,
+
+ COVERAGE_VARIATION_FLAG = 0x00u, /* Not supported. */
+
+ COVERAGE_CHECK_FLAGS = 0x07u,
+ COVERAGE_CHECK_HORIZONTAL = 0x01u
+ };
+
+ protected:
+ UINT16 versionZ; /* Unused. */
+ UINT16 length; /* Length of the subtable (including this header). */
+ UINT8 format; /* Subtable format. */
+ UINT8 coverage; /* Coverage bits. */
+ KernSubTable subtable; /* Subtable data. */
+ public:
+ DEFINE_SIZE_MIN (6);
+ };
+
+ protected:
+ UINT16 version; /* Version--0x0000u */
+ UINT16 nTables; /* Number of subtables in the kerning table. */
+ UINT8 data[VAR];
+ public:
+ DEFINE_SIZE_ARRAY (4, data);
+};
+
+struct KernAAT : KernTable<KernAAT>
+{
+ friend struct KernTable<KernAAT>;
+
+ static const uint32_t VERSION = 0x00010000u;
+
+ struct SubTableWrapper : KernSubTableWrapper<SubTableWrapper>
+ {
+ friend struct KernSubTableWrapper<SubTableWrapper>;
+
+ enum coverage_flags_t {
+ COVERAGE_DIRECTION_FLAG = 0x80u,
+ COVERAGE_CROSSSTREAM_FLAG = 0x40u,
+ COVERAGE_VARIATION_FLAG = 0x20u,
+
+ COVERAGE_OVERRIDE_FLAG = 0x00u, /* Not supported. */
+
+ COVERAGE_CHECK_FLAGS = 0xE0u,
+ COVERAGE_CHECK_HORIZONTAL = 0x00u
+ };
+
+ protected:
+ UINT32 length; /* Length of the subtable (including this header). */
+ UINT8 coverage; /* Coverage bits. */
+ UINT8 format; /* Subtable format. */
+ UINT16 tupleIndex; /* The tuple index (used for variations fonts).
+ * This value specifies which tuple this subtable covers. */
+ KernSubTable subtable; /* Subtable data. */
+ public:
+ DEFINE_SIZE_MIN (8);
+ };
+
+ protected:
+ UINT32 version; /* Version--0x00010000u */
+ UINT32 nTables; /* Number of subtables in the kerning table. */
+ UINT8 data[VAR];
+ public:
+ DEFINE_SIZE_ARRAY (8, data);
+};
+
+struct kern
+{
+ static const hb_tag_t tableTag = HB_OT_TAG_kern;
+
+ inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right, unsigned int table_length) const
+ {
+ switch (u.major) {
+ case 0: return u.ot.get_h_kerning (left, right, table_length);
+ case 1: return u.aat.get_h_kerning (left, right, table_length);
+ default:return 0;
+ }
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (!u.major.sanitize (c)) return_trace (false);
+ switch (u.major) {
+ case 0: return_trace (u.ot.sanitize (c));
+ case 1: return_trace (u.aat.sanitize (c));
+ default:return_trace (true);
+ }
+ }
+
+ struct accelerator_t
+ {
+ inline void init (hb_face_t *face)
+ {
+ blob = Sanitizer<kern>::sanitize (face->reference_table (HB_OT_TAG_kern));
+ table = Sanitizer<kern>::lock_instance (blob);
+ table_length = hb_blob_get_length (blob);
+ }
+ inline void fini (void)
+ {
+ hb_blob_destroy (blob);
+ }
+
+ inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
+ { return table->get_h_kerning (left, right, table_length); }
+
+ private:
+ hb_blob_t *blob;
+ const kern *table;
+ unsigned int table_length;
+ };
+
+ protected:
+ union {
+ UINT16 major;
+ KernOT ot;
+ KernAAT aat;
+ } u;
+ public:
+ DEFINE_SIZE_UNION (2, major);
+};
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_KERN_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh
index 62ca7a348e..5e699e1967 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh
@@ -29,6 +29,8 @@
#ifndef HB_OT_LAYOUT_COMMON_PRIVATE_HH
#define HB_OT_LAYOUT_COMMON_PRIVATE_HH
+#include "hb-private.hh"
+#include "hb-debug.hh"
#include "hb-ot-layout-private.hh"
#include "hb-open-type-private.hh"
#include "hb-set-private.hh"
@@ -45,12 +47,6 @@
namespace OT {
-#define TRACE_DISPATCH(this, format) \
- hb_auto_trace_t<context_t::max_debug_depth, typename context_t::return_t> trace \
- (&c->debug_depth, c->get_name (), this, HB_FUNC, \
- "format %d", (int) format);
-
-
#define NOT_COVERED ((unsigned int) -1)
@@ -159,13 +155,13 @@ struct RangeRecord
}
template <typename set_t>
- inline void add_coverage (set_t *glyphs) const {
- glyphs->add_range (start, end);
+ inline bool add_coverage (set_t *glyphs) const {
+ return glyphs->add_range (start, end);
}
GlyphID start; /* First GlyphID in the range */
GlyphID end; /* Last GlyphID in the range */
- USHORT value; /* Value */
+ UINT16 value; /* Value */
public:
DEFINE_SIZE_STATIC (6);
};
@@ -179,7 +175,7 @@ struct IndexArray : ArrayOf<Index>
unsigned int *_indexes /* OUT */) const
{
if (_count) {
- const USHORT *arr = this->sub_array (start_offset, _count);
+ const UINT16 *arr = this->sub_array (start_offset, _count);
unsigned int count = *_count;
for (unsigned int i = 0; i < count; i++)
_indexes[i] = arr[i];
@@ -214,15 +210,15 @@ struct LangSys
}
inline bool sanitize (hb_sanitize_context_t *c,
- const Record<LangSys>::sanitize_closure_t * = NULL) const
+ const Record<LangSys>::sanitize_closure_t * = nullptr) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) && featureIndex.sanitize (c));
}
- Offset<> lookupOrderZ; /* = Null (reserved for an offset to a
+ Offset16 lookupOrderZ; /* = Null (reserved for an offset to a
* reordering table) */
- USHORT reqFeatureIndex;/* Index of a feature required for this
+ UINT16 reqFeatureIndex;/* Index of a feature required for this
* language system--if no required features
* = 0xFFFFu */
IndexArray featureIndex; /* Array of indices into the FeatureList */
@@ -254,7 +250,7 @@ struct Script
inline const LangSys& get_default_lang_sys (void) const { return this+defaultLangSys; }
inline bool sanitize (hb_sanitize_context_t *c,
- const Record<Script>::sanitize_closure_t * = NULL) const
+ const Record<Script>::sanitize_closure_t * = nullptr) const
{
TRACE_SANITIZE (this);
return_trace (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, this));
@@ -347,12 +343,12 @@ struct FeatureParamsSize
return_trace (true);
}
- USHORT designSize; /* Represents the design size in 720/inch
+ UINT16 designSize; /* Represents the design size in 720/inch
* units (decipoints). The design size entry
* must be non-zero. When there is a design
* size but no recommended size range, the
* rest of the array will consist of zeros. */
- USHORT subfamilyID; /* Has no independent meaning, but serves
+ UINT16 subfamilyID; /* Has no independent meaning, but serves
* as an identifier that associates fonts
* in a subfamily. All fonts which share a
* Preferred or Font Family name and which
@@ -362,7 +358,7 @@ struct FeatureParamsSize
* same subfamily value. If this value is
* zero, the remaining fields in the array
* will be ignored. */
- USHORT subfamilyNameID;/* If the preceding value is non-zero, this
+ UINT16 subfamilyNameID;/* If the preceding value is non-zero, this
* value must be set in the range 256 - 32767
* (inclusive). It records the value of a
* field in the name table, which must
@@ -376,10 +372,10 @@ struct FeatureParamsSize
* subfamily in a menu. Applications will
* choose the appropriate version based on
* their selection criteria. */
- USHORT rangeStart; /* Large end of the recommended usage range
+ UINT16 rangeStart; /* Large end of the recommended usage range
* (inclusive), stored in 720/inch units
* (decipoints). */
- USHORT rangeEnd; /* Small end of the recommended usage range
+ UINT16 rangeEnd; /* Small end of the recommended usage range
(exclusive), stored in 720/inch units
* (decipoints). */
public:
@@ -397,12 +393,12 @@ struct FeatureParamsStylisticSet
return_trace (c->check_struct (this));
}
- USHORT version; /* (set to 0): This corresponds to a “minor”
+ UINT16 version; /* (set to 0): This corresponds to a “minor”
* version number. Additional data may be
* added to the end of this Feature Parameters
* table in the future. */
- USHORT uiNameID; /* The 'name' table name ID that specifies a
+ UINT16 uiNameID; /* The 'name' table name ID that specifies a
* string (or strings, for multiple languages)
* for a user-interface label for this
* feature. The values of uiLabelNameId and
@@ -430,25 +426,25 @@ struct FeatureParamsCharacterVariants
characters.sanitize (c));
}
- USHORT format; /* Format number is set to 0. */
- USHORT featUILableNameID; /* The ‘name’ table name ID that
+ UINT16 format; /* Format number is set to 0. */
+ UINT16 featUILableNameID; /* The ‘name’ table name ID that
* specifies a string (or strings,
* for multiple languages) for a
* user-interface label for this
- * feature. (May be NULL.) */
- USHORT featUITooltipTextNameID;/* The ‘name’ table name ID that
+ * feature. (May be nullptr.) */
+ UINT16 featUITooltipTextNameID;/* The ‘name’ table name ID that
* specifies a string (or strings,
* for multiple languages) that an
* application can use for tooltip
* text for this feature. (May be
- * NULL.) */
- USHORT sampleTextNameID; /* The ‘name’ table name ID that
+ * nullptr.) */
+ UINT16 sampleTextNameID; /* The ‘name’ table name ID that
* specifies sample text that
* illustrates the effect of this
- * feature. (May be NULL.) */
- USHORT numNamedParameters; /* Number of named parameters. (May
+ * feature. (May be nullptr.) */
+ UINT16 numNamedParameters; /* Number of named parameters. (May
* be zero.) */
- USHORT firstParamUILabelNameID;/* The first ‘name’ table name ID
+ UINT16 firstParamUILabelNameID;/* The first ‘name’ table name ID
* used to specify strings for
* user-interface labels for the
* feature parameters. (Must be zero
@@ -507,7 +503,7 @@ struct Feature
{ return this+featureParams; }
inline bool sanitize (hb_sanitize_context_t *c,
- const Record<Feature>::sanitize_closure_t *closure = NULL) const
+ const Record<Feature>::sanitize_closure_t *closure = nullptr) const
{
TRACE_SANITIZE (this);
if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c))))
@@ -566,7 +562,7 @@ struct Feature
typedef RecordListOf<Feature> FeatureList;
-struct LookupFlag : USHORT
+struct LookupFlag : UINT16
{
enum Flags {
RightToLeft = 0x0001u,
@@ -612,7 +608,7 @@ struct Lookup
unsigned int flag = lookupFlag;
if (unlikely (flag & LookupFlag::UseMarkFilteringSet))
{
- const USHORT &markFilteringSet = StructAfter<USHORT> (subTable);
+ const UINT16 &markFilteringSet = StructAfter<UINT16> (subTable);
flag += (markFilteringSet << 16);
}
return flag;
@@ -644,7 +640,7 @@ struct Lookup
if (unlikely (!subTable.serialize (c, num_subtables))) return_trace (false);
if (lookupFlag & LookupFlag::UseMarkFilteringSet)
{
- USHORT &markFilteringSet = StructAfter<USHORT> (subTable);
+ UINT16 &markFilteringSet = StructAfter<UINT16> (subTable);
markFilteringSet.set (lookup_props >> 16);
}
return_trace (true);
@@ -657,18 +653,18 @@ struct Lookup
if (!(c->check_struct (this) && subTable.sanitize (c))) return_trace (false);
if (lookupFlag & LookupFlag::UseMarkFilteringSet)
{
- const USHORT &markFilteringSet = StructAfter<USHORT> (subTable);
+ const UINT16 &markFilteringSet = StructAfter<UINT16> (subTable);
if (!markFilteringSet.sanitize (c)) return_trace (false);
}
return_trace (true);
}
private:
- USHORT lookupType; /* Different enumerations for GSUB and GPOS */
- USHORT lookupFlag; /* Lookup qualifiers */
- ArrayOf<Offset<> >
+ UINT16 lookupType; /* Different enumerations for GSUB and GPOS */
+ UINT16 lookupFlag; /* Lookup qualifiers */
+ ArrayOf<Offset16>
subTable; /* Array of SubTables */
- USHORT markFilteringSetX[VAR]; /* Index (base 0) into GDEF mark glyph sets
+ UINT16 markFilteringSetX[VAR]; /* Index (base 0) into GDEF mark glyph sets
* structure. This field is only present if bit
* UseMarkFilteringSet of lookup flags is set. */
public:
@@ -690,7 +686,7 @@ struct CoverageFormat1
inline unsigned int get_coverage (hb_codepoint_t glyph_id) const
{
int i = glyphArray.bsearch (glyph_id);
- ASSERT_STATIC (((unsigned int) -1) == NOT_COVERED);
+ static_assert ((((unsigned int) -1) == NOT_COVERED), "");
return i;
}
@@ -719,10 +715,8 @@ struct CoverageFormat1
}
template <typename set_t>
- inline void add_coverage (set_t *glyphs) const {
- unsigned int count = glyphArray.len;
- for (unsigned int i = 0; i < count; i++)
- glyphs->add (glyphArray[i]);
+ inline bool add_coverage (set_t *glyphs) const {
+ return glyphs->add_sorted_array (glyphArray.array, glyphArray.len);
}
public:
@@ -741,7 +735,7 @@ struct CoverageFormat1
private:
protected:
- USHORT coverageFormat; /* Format identifier--format = 1 */
+ UINT16 coverageFormat; /* Format identifier--format = 1 */
SortedArrayOf<GlyphID>
glyphArray; /* Array of GlyphIDs--in numerical order */
public:
@@ -821,10 +815,12 @@ struct CoverageFormat2
}
template <typename set_t>
- inline void add_coverage (set_t *glyphs) const {
+ inline bool add_coverage (set_t *glyphs) const {
unsigned int count = rangeRecord.len;
for (unsigned int i = 0; i < count; i++)
- rangeRecord[i].add_coverage (glyphs);
+ if (unlikely (!rangeRecord[i].add_coverage (glyphs)))
+ return false;
+ return true;
}
public:
@@ -864,7 +860,7 @@ struct CoverageFormat2
private:
protected:
- USHORT coverageFormat; /* Format identifier--format = 2 */
+ UINT16 coverageFormat; /* Format identifier--format = 2 */
SortedArrayOf<RangeRecord>
rangeRecord; /* Array of glyph ranges--ordered by
* Start GlyphID. rangeCount entries
@@ -931,17 +927,19 @@ struct Coverage
}
}
+ /* Might return false if array looks unsorted.
+ * Used for faster rejection of corrupt data. */
template <typename set_t>
- inline void add_coverage (set_t *glyphs) const {
+ inline bool add_coverage (set_t *glyphs) const {
switch (u.format) {
- case 1: u.format1.add_coverage (glyphs); break;
- case 2: u.format2.add_coverage (glyphs); break;
- default: break;
+ case 1: return u.format1.add_coverage (glyphs);
+ case 2: return u.format2.add_coverage (glyphs);
+ default:return false;
}
}
struct Iter {
- Iter (void) : format (0) {};
+ Iter (void) : format (0), u () {};
inline void init (const Coverage &c_) {
format = c_.u.format;
switch (format) {
@@ -982,14 +980,14 @@ struct Coverage
private:
unsigned int format;
union {
+ CoverageFormat2::Iter format2; /* Put this one first since it's larger; helps shut up compiler. */
CoverageFormat1::Iter format1;
- CoverageFormat2::Iter format2;
} u;
};
protected:
union {
- USHORT format; /* Format identifier */
+ UINT16 format; /* Format identifier */
CoverageFormat1 format1;
CoverageFormat2 format2;
} u;
@@ -1022,11 +1020,36 @@ struct ClassDefFormat1
}
template <typename set_t>
- inline void add_class (set_t *glyphs, unsigned int klass) const {
+ inline bool add_coverage (set_t *glyphs) const {
+ unsigned int start = 0;
unsigned int count = classValue.len;
for (unsigned int i = 0; i < count; i++)
+ {
+ if (classValue[i])
+ continue;
+
+ if (start != i)
+ if (unlikely (!glyphs->add_range (startGlyph + start, startGlyph + i)))
+ return false;
+
+ start = i + 1;
+ }
+ if (start != count)
+ if (unlikely (!glyphs->add_range (startGlyph + start, startGlyph + count)))
+ return false;
+
+ return true;
+ }
+
+ template <typename set_t>
+ inline bool add_class (set_t *glyphs, unsigned int klass) const {
+ unsigned int count = classValue.len;
+ for (unsigned int i = 0; i < count; i++)
+ {
if (classValue[i] == klass)
glyphs->add (startGlyph + i);
+ }
+ return true;
}
inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
@@ -1051,9 +1074,9 @@ struct ClassDefFormat1
}
protected:
- USHORT classFormat; /* Format identifier--format = 1 */
+ UINT16 classFormat; /* Format identifier--format = 1 */
GlyphID startGlyph; /* First GlyphID of the classValueArray */
- ArrayOf<USHORT>
+ ArrayOf<UINT16>
classValue; /* Array of Class Values--one per GlyphID */
public:
DEFINE_SIZE_ARRAY (6, classValue);
@@ -1079,11 +1102,25 @@ struct ClassDefFormat2
}
template <typename set_t>
- inline void add_class (set_t *glyphs, unsigned int klass) const {
+ inline bool add_coverage (set_t *glyphs) const {
unsigned int count = rangeRecord.len;
for (unsigned int i = 0; i < count; i++)
+ if (rangeRecord[i].value)
+ if (unlikely (!rangeRecord[i].add_coverage (glyphs)))
+ return false;
+ return true;
+ }
+
+ template <typename set_t>
+ inline bool add_class (set_t *glyphs, unsigned int klass) const {
+ unsigned int count = rangeRecord.len;
+ for (unsigned int i = 0; i < count; i++)
+ {
if (rangeRecord[i].value == klass)
- rangeRecord[i].add_coverage (glyphs);
+ if (unlikely (!rangeRecord[i].add_coverage (glyphs)))
+ return false;
+ }
+ return true;
}
inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
@@ -1111,7 +1148,7 @@ struct ClassDefFormat2
}
protected:
- USHORT classFormat; /* Format identifier--format = 2 */
+ UINT16 classFormat; /* Format identifier--format = 2 */
SortedArrayOf<RangeRecord>
rangeRecord; /* Array of glyph ranges--ordered by
* Start GlyphID */
@@ -1141,11 +1178,25 @@ struct ClassDef
}
}
- inline void add_class (hb_set_t *glyphs, unsigned int klass) const {
+ /* Might return false if array looks unsorted.
+ * Used for faster rejection of corrupt data. */
+ template <typename set_t>
+ inline bool add_coverage (set_t *glyphs) const {
+ switch (u.format) {
+ case 1: return u.format1.add_coverage (glyphs);
+ case 2: return u.format2.add_coverage (glyphs);
+ default:return false;
+ }
+ }
+
+ /* Might return false if array looks unsorted.
+ * Used for faster rejection of corrupt data. */
+ template <typename set_t>
+ inline bool add_class (set_t *glyphs, unsigned int klass) const {
switch (u.format) {
- case 1: u.format1.add_class (glyphs, klass); return;
- case 2: u.format2.add_class (glyphs, klass); return;
- default:return;
+ case 1: return u.format1.add_class (glyphs, klass);
+ case 2: return u.format2.add_class (glyphs, klass);
+ default:return false;
}
}
@@ -1159,7 +1210,7 @@ struct ClassDef
protected:
union {
- USHORT format; /* Format identifier */
+ UINT16 format; /* Format identifier */
ClassDefFormat1 format1;
ClassDefFormat2 format2;
} u;
@@ -1244,8 +1295,8 @@ struct VarRegionList
}
protected:
- USHORT axisCount;
- USHORT regionCount;
+ UINT16 axisCount;
+ UINT16 regionCount;
VarRegionAxis axesZ[VAR];
public:
DEFINE_SIZE_ARRAY (4, axesZ);
@@ -1269,13 +1320,13 @@ struct VarData
unsigned int count = regionIndices.len;
unsigned int scount = shortCount;
- const BYTE *bytes = &StructAfter<BYTE> (regionIndices);
- const BYTE *row = bytes + inner * (scount + count);
+ const UINT8 *bytes = &StructAfter<UINT8> (regionIndices);
+ const UINT8 *row = bytes + inner * (scount + count);
float delta = 0.;
unsigned int i = 0;
- const SHORT *scursor = reinterpret_cast<const SHORT *> (row);
+ const INT16 *scursor = reinterpret_cast<const INT16 *> (row);
for (; i < scount; i++)
{
float scalar = regions.evaluate (regionIndices.array[i], coords, coord_count);
@@ -1297,15 +1348,15 @@ struct VarData
return_trace (c->check_struct (this) &&
regionIndices.sanitize(c) &&
shortCount <= regionIndices.len &&
- c->check_array (&StructAfter<BYTE> (regionIndices),
+ c->check_array (&StructAfter<UINT8> (regionIndices),
get_row_size (), itemCount));
}
protected:
- USHORT itemCount;
- USHORT shortCount;
- ArrayOf<USHORT> regionIndices;
- BYTE bytesX[VAR];
+ UINT16 itemCount;
+ UINT16 shortCount;
+ ArrayOf<UINT16> regionIndices;
+ UINT8 bytesX[VAR];
public:
DEFINE_SIZE_ARRAY2 (6, regionIndices, bytesX);
};
@@ -1323,6 +1374,14 @@ struct VariationStore
this+regions);
}
+ inline float get_delta (unsigned int index,
+ int *coords, unsigned int coord_count) const
+ {
+ unsigned int outer = index >> 16;
+ unsigned int inner = index & 0xFFFF;
+ return get_delta (outer, inner, coords, coord_count);
+ }
+
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -1333,9 +1392,9 @@ struct VariationStore
}
protected:
- USHORT format;
- OffsetTo<VarRegionList, ULONG> regions;
- OffsetArrayOf<VarData, ULONG> dataSets;
+ UINT16 format;
+ LOffsetTo<VarRegionList> regions;
+ OffsetArrayOf<VarData, UINT32> dataSets;
public:
DEFINE_SIZE_ARRAY (8, dataSets);
};
@@ -1362,8 +1421,8 @@ struct ConditionFormat1
}
protected:
- USHORT format; /* Format identifier--format = 1 */
- USHORT axisIndex;
+ UINT16 format; /* Format identifier--format = 1 */
+ UINT16 axisIndex;
F2DOT14 filterRangeMinValue;
F2DOT14 filterRangeMaxValue;
public:
@@ -1392,7 +1451,7 @@ struct Condition
protected:
union {
- USHORT format; /* Format identifier */
+ UINT16 format; /* Format identifier */
ConditionFormat1 format1;
} u;
public:
@@ -1417,7 +1476,7 @@ struct ConditionSet
}
protected:
- OffsetArrayOf<Condition, ULONG> conditions;
+ OffsetArrayOf<Condition, UINT32> conditions;
public:
DEFINE_SIZE_ARRAY (2, conditions);
};
@@ -1433,8 +1492,8 @@ struct FeatureTableSubstitutionRecord
}
protected:
- USHORT featureIndex;
- OffsetTo<Feature, ULONG> feature;
+ UINT16 featureIndex;
+ LOffsetTo<Feature> feature;
public:
DEFINE_SIZE_STATIC (6);
};
@@ -1450,7 +1509,7 @@ struct FeatureTableSubstitution
if (record.featureIndex == feature_index)
return &(this+record.feature);
}
- return NULL;
+ return nullptr;
}
inline bool sanitize (hb_sanitize_context_t *c) const
@@ -1481,9 +1540,9 @@ struct FeatureVariationRecord
}
protected:
- OffsetTo<ConditionSet, ULONG>
+ LOffsetTo<ConditionSet>
conditions;
- OffsetTo<FeatureTableSubstitution, ULONG>
+ LOffsetTo<FeatureTableSubstitution>
substitutions;
public:
DEFINE_SIZE_STATIC (8);
@@ -1527,7 +1586,7 @@ struct FeatureVariations
protected:
FixedVersion<> version; /* Version--0x00010000u */
- ArrayOf<FeatureVariationRecord, ULONG>
+ LArrayOf<FeatureVariationRecord>
varRecords;
public:
DEFINE_SIZE_ARRAY (8, varRecords);
@@ -1553,8 +1612,8 @@ struct HintingDevice
inline unsigned int get_size (void) const
{
unsigned int f = deltaFormat;
- if (unlikely (f < 1 || f > 3 || startSize > endSize)) return 3 * USHORT::static_size;
- return USHORT::static_size * (4 + ((endSize - startSize) >> (4 - f)));
+ if (unlikely (f < 1 || f > 3 || startSize > endSize)) return 3 * UINT16::static_size;
+ return UINT16::static_size * (4 + ((endSize - startSize) >> (4 - f)));
}
inline bool sanitize (hb_sanitize_context_t *c) const
@@ -1599,14 +1658,14 @@ struct HintingDevice
}
protected:
- USHORT startSize; /* Smallest size to correct--in ppem */
- USHORT endSize; /* Largest size to correct--in ppem */
- USHORT deltaFormat; /* Format of DeltaValue array data: 1, 2, or 3
+ UINT16 startSize; /* Smallest size to correct--in ppem */
+ UINT16 endSize; /* Largest size to correct--in ppem */
+ UINT16 deltaFormat; /* Format of DeltaValue array data: 1, 2, or 3
* 1 Signed 2-bit value, 8 values per uint16
* 2 Signed 4-bit value, 4 values per uint16
* 3 Signed 8-bit value, 2 values per uint16
*/
- USHORT deltaValue[VAR]; /* Array of compressed data */
+ UINT16 deltaValue[VAR]; /* Array of compressed data */
public:
DEFINE_SIZE_ARRAY (6, deltaValue);
};
@@ -1637,9 +1696,9 @@ struct VariationDevice
}
protected:
- USHORT outerIndex;
- USHORT innerIndex;
- USHORT deltaFormat; /* Format identifier for this table: 0x0x8000 */
+ UINT16 outerIndex;
+ UINT16 innerIndex;
+ UINT16 deltaFormat; /* Format identifier for this table: 0x0x8000 */
public:
DEFINE_SIZE_STATIC (6);
};
@@ -1647,10 +1706,10 @@ struct VariationDevice
struct DeviceHeader
{
protected:
- USHORT reserved1;
- USHORT reserved2;
+ UINT16 reserved1;
+ UINT16 reserved2;
public:
- USHORT format; /* Format identifier */
+ UINT16 format; /* Format identifier */
public:
DEFINE_SIZE_STATIC (6);
};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh
index b70cbb7a38..eed46dd672 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh
@@ -41,7 +41,7 @@ namespace OT {
* Attachment List Table
*/
-typedef ArrayOf<USHORT> AttachPoint; /* Array of contour point indices--in
+typedef ArrayOf<UINT16> AttachPoint; /* Array of contour point indices--in
* increasing numerical order */
struct AttachList
@@ -62,7 +62,7 @@ struct AttachList
const AttachPoint &points = this+attachPoint[index];
if (point_count) {
- const USHORT *array = points.sub_array (start_offset, point_count);
+ const UINT16 *array = points.sub_array (start_offset, point_count);
unsigned int count = *point_count;
for (unsigned int i = 0; i < count; i++)
point_array[i] = array[i];
@@ -109,8 +109,8 @@ struct CaretValueFormat1
}
protected:
- USHORT caretValueFormat; /* Format identifier--format = 1 */
- SHORT coordinate; /* X or Y value, in design units */
+ UINT16 caretValueFormat; /* Format identifier--format = 1 */
+ INT16 coordinate; /* X or Y value, in design units */
public:
DEFINE_SIZE_STATIC (4);
};
@@ -136,8 +136,8 @@ struct CaretValueFormat2
}
protected:
- USHORT caretValueFormat; /* Format identifier--format = 2 */
- USHORT caretValuePoint; /* Contour point index on glyph */
+ UINT16 caretValueFormat; /* Format identifier--format = 2 */
+ UINT16 caretValuePoint; /* Contour point index on glyph */
public:
DEFINE_SIZE_STATIC (4);
};
@@ -160,8 +160,8 @@ struct CaretValueFormat3
}
protected:
- USHORT caretValueFormat; /* Format identifier--format = 3 */
- SHORT coordinate; /* X or Y value, in design units */
+ UINT16 caretValueFormat; /* Format identifier--format = 3 */
+ INT16 coordinate; /* X or Y value, in design units */
OffsetTo<Device>
deviceTable; /* Offset to Device table for X or Y
* value--from beginning of CaretValue
@@ -199,7 +199,7 @@ struct CaretValue
protected:
union {
- USHORT format; /* Format identifier */
+ UINT16 format; /* Format identifier */
CaretValueFormat1 format1;
CaretValueFormat2 format2;
CaretValueFormat3 format3;
@@ -294,8 +294,8 @@ struct MarkGlyphSetsFormat1
}
protected:
- USHORT format; /* Format identifier--format = 1 */
- ArrayOf<OffsetTo<Coverage, ULONG> >
+ UINT16 format; /* Format identifier--format = 1 */
+ ArrayOf<LOffsetTo<Coverage> >
coverage; /* Array of long offsets to mark set
* coverage tables */
public:
@@ -324,7 +324,7 @@ struct MarkGlyphSets
protected:
union {
- USHORT format; /* Format identifier */
+ UINT16 format; /* Format identifier */
MarkGlyphSetsFormat1 format1;
} u;
public:
@@ -404,9 +404,9 @@ struct GDEF
{
unsigned int klass = get_glyph_class (glyph);
- ASSERT_STATIC ((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH == (unsigned int) LookupFlag::IgnoreBaseGlyphs);
- ASSERT_STATIC ((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE == (unsigned int) LookupFlag::IgnoreLigatures);
- ASSERT_STATIC ((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_MARK == (unsigned int) LookupFlag::IgnoreMarks);
+ static_assert (((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH == (unsigned int) LookupFlag::IgnoreBaseGlyphs), "");
+ static_assert (((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE == (unsigned int) LookupFlag::IgnoreLigatures), "");
+ static_assert (((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_MARK == (unsigned int) LookupFlag::IgnoreMarks), "");
switch (klass) {
default: return 0;
@@ -443,7 +443,7 @@ struct GDEF
* definitions--from beginning of GDEF
* header (may be NULL). Introduced
* in version 0x00010002. */
- OffsetTo<VariationStore, ULONG>
+ LOffsetTo<VariationStore>
varStore; /* Offset to the table of Item Variation
* Store--from beginning of GDEF
* header (may be NULL). Introduced
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh
index 952fd60fec..b344d793c7 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh
@@ -51,11 +51,11 @@ enum attach_type_t {
/* Shared Tables: ValueRecord, Anchor Table, and MarkArray */
-typedef USHORT Value;
+typedef UINT16 Value;
typedef Value ValueRecord[VAR];
-struct ValueFormat : USHORT
+struct ValueFormat : UINT16
{
enum Flags {
xPlacement = 0x0001u, /* Includes horizontal adjustment for placement */
@@ -74,14 +74,14 @@ struct ValueFormat : USHORT
/* All fields are options. Only those available advance the value pointer. */
#if 0
- SHORT xPlacement; /* Horizontal adjustment for
+ INT16 xPlacement; /* Horizontal adjustment for
* placement--in design units */
- SHORT yPlacement; /* Vertical adjustment for
+ INT16 yPlacement; /* Vertical adjustment for
* placement--in design units */
- SHORT xAdvance; /* Horizontal adjustment for
+ INT16 xAdvance; /* Horizontal adjustment for
* advance--in design units (only used
* for horizontal writing) */
- SHORT yAdvance; /* Vertical adjustment for advance--in
+ INT16 yAdvance; /* Vertical adjustment for advance--in
* design units (only used for vertical
* writing) */
Offset xPlaDevice; /* Offset to Device table for
@@ -178,8 +178,8 @@ struct ValueFormat : USHORT
static inline const OffsetTo<Device>& get_device (const Value* value)
{ return *CastP<OffsetTo<Device> > (value); }
- static inline const SHORT& get_short (const Value* value)
- { return *CastP<SHORT> (value); }
+ static inline const INT16& get_short (const Value* value)
+ { return *CastP<INT16> (value); }
public:
@@ -247,9 +247,9 @@ struct AnchorFormat1
}
protected:
- USHORT format; /* Format identifier--format = 1 */
- SHORT xCoordinate; /* Horizontal value--in design units */
- SHORT yCoordinate; /* Vertical value--in design units */
+ UINT16 format; /* Format identifier--format = 1 */
+ INT16 xCoordinate; /* Horizontal value--in design units */
+ INT16 yCoordinate; /* Vertical value--in design units */
public:
DEFINE_SIZE_STATIC (6);
};
@@ -278,10 +278,10 @@ struct AnchorFormat2
}
protected:
- USHORT format; /* Format identifier--format = 2 */
- SHORT xCoordinate; /* Horizontal value--in design units */
- SHORT yCoordinate; /* Vertical value--in design units */
- USHORT anchorPoint; /* Index to glyph contour point */
+ UINT16 format; /* Format identifier--format = 2 */
+ INT16 xCoordinate; /* Horizontal value--in design units */
+ INT16 yCoordinate; /* Vertical value--in design units */
+ UINT16 anchorPoint; /* Index to glyph contour point */
public:
DEFINE_SIZE_STATIC (8);
};
@@ -308,9 +308,9 @@ struct AnchorFormat3
}
protected:
- USHORT format; /* Format identifier--format = 3 */
- SHORT xCoordinate; /* Horizontal value--in design units */
- SHORT yCoordinate; /* Vertical value--in design units */
+ UINT16 format; /* Format identifier--format = 3 */
+ INT16 xCoordinate; /* Horizontal value--in design units */
+ INT16 yCoordinate; /* Vertical value--in design units */
OffsetTo<Device>
xDeviceTable; /* Offset to Device table for X
* coordinate-- from beginning of
@@ -351,7 +351,7 @@ struct Anchor
protected:
union {
- USHORT format; /* Format identifier */
+ UINT16 format; /* Format identifier */
AnchorFormat1 format1;
AnchorFormat2 format2;
AnchorFormat3 format3;
@@ -382,7 +382,7 @@ struct AnchorMatrix
return_trace (true);
}
- USHORT rows; /* Number of rows */
+ UINT16 rows; /* Number of rows */
protected:
OffsetTo<Anchor>
matrixZ[VAR]; /* Matrix of offsets to Anchor tables--
@@ -403,7 +403,7 @@ struct MarkRecord
}
protected:
- USHORT klass; /* Class defined for this mark */
+ UINT16 klass; /* Class defined for this mark */
OffsetTo<Anchor>
markAnchor; /* Offset to Anchor table--from
* beginning of MarkArray table */
@@ -432,6 +432,7 @@ struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage orde
hb_position_t mark_x, mark_y, base_x, base_y;
+ buffer->unsafe_to_break (glyph_pos, buffer->idx);
mark_anchor.get_anchor (c, buffer->cur().codepoint, &mark_x, &mark_y);
glyph_anchor.get_anchor (c, buffer->info[glyph_pos].codepoint, &base_x, &base_y);
@@ -461,7 +462,7 @@ struct SinglePosFormat1
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
TRACE_COLLECT_GLYPHS (this);
- (this+coverage).add_coverage (c->input);
+ if (unlikely (!(this+coverage).add_coverage (c->input))) return;
}
inline const Coverage &get_coverage (void) const
@@ -491,7 +492,7 @@ struct SinglePosFormat1
}
protected:
- USHORT format; /* Format identifier--format = 1 */
+ UINT16 format; /* Format identifier--format = 1 */
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of subtable */
@@ -509,7 +510,7 @@ struct SinglePosFormat2
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
TRACE_COLLECT_GLYPHS (this);
- (this+coverage).add_coverage (c->input);
+ if (unlikely (!(this+coverage).add_coverage (c->input))) return;
}
inline const Coverage &get_coverage (void) const
@@ -543,13 +544,13 @@ struct SinglePosFormat2
}
protected:
- USHORT format; /* Format identifier--format = 2 */
+ UINT16 format; /* Format identifier--format = 2 */
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of subtable */
ValueFormat valueFormat; /* Defines the types of data in the
* ValueRecord */
- USHORT valueCount; /* Number of ValueRecords */
+ UINT16 valueCount; /* Number of ValueRecords */
ValueRecord values; /* Array of ValueRecords--positioning
* values applied to glyphs */
public:
@@ -572,7 +573,7 @@ struct SinglePos
protected:
union {
- USHORT format; /* Format identifier */
+ UINT16 format; /* Format identifier */
SinglePosFormat1 format1;
SinglePosFormat2 format2;
} u;
@@ -603,15 +604,10 @@ struct PairSet
TRACE_COLLECT_GLYPHS (this);
unsigned int len1 = valueFormats[0].get_len ();
unsigned int len2 = valueFormats[1].get_len ();
- unsigned int record_size = USHORT::static_size * (1 + len1 + len2);
+ unsigned int record_size = UINT16::static_size * (1 + len1 + len2);
const PairValueRecord *record = CastP<PairValueRecord> (arrayZ);
- unsigned int count = len;
- for (unsigned int i = 0; i < count; i++)
- {
- c->input->add (record->secondGlyph);
- record = &StructAtOffset<PairValueRecord> (record, record_size);
- }
+ c->input->add_array (&record->secondGlyph, len, record_size);
}
inline bool apply (hb_apply_context_t *c,
@@ -622,7 +618,7 @@ struct PairSet
hb_buffer_t *buffer = c->buffer;
unsigned int len1 = valueFormats[0].get_len ();
unsigned int len2 = valueFormats[1].get_len ();
- unsigned int record_size = USHORT::static_size * (1 + len1 + len2);
+ unsigned int record_size = UINT16::static_size * (1 + len1 + len2);
const PairValueRecord *record_array = CastP<PairValueRecord> (arrayZ);
unsigned int count = len;
@@ -643,6 +639,7 @@ struct PairSet
min = mid + 1;
else
{
+ buffer->unsafe_to_break (buffer->idx, pos + 1);
valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos());
valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]);
if (len2)
@@ -666,7 +663,7 @@ struct PairSet
{
TRACE_SANITIZE (this);
if (!(c->check_struct (this)
- && c->check_array (arrayZ, USHORT::static_size * closure->stride, len))) return_trace (false);
+ && c->check_array (arrayZ, UINT16::static_size * closure->stride, len))) return_trace (false);
unsigned int count = len;
const PairValueRecord *record = CastP<PairValueRecord> (arrayZ);
@@ -675,8 +672,8 @@ struct PairSet
}
protected:
- USHORT len; /* Number of PairValueRecords */
- USHORT arrayZ[VAR]; /* Array of PairValueRecords--ordered
+ UINT16 len; /* Number of PairValueRecords */
+ UINT16 arrayZ[VAR]; /* Array of PairValueRecords--ordered
* by GlyphID of the second glyph */
public:
DEFINE_SIZE_ARRAY (2, arrayZ);
@@ -687,7 +684,7 @@ struct PairPosFormat1
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
TRACE_COLLECT_GLYPHS (this);
- (this+coverage).add_coverage (c->input);
+ if (unlikely (!(this+coverage).add_coverage (c->input))) return;
unsigned int count = pairSet.len;
for (unsigned int i = 0; i < count; i++)
(this+pairSet[i]).collect_glyphs (c, valueFormat);
@@ -731,7 +728,7 @@ struct PairPosFormat1
}
protected:
- USHORT format; /* Format identifier--format = 1 */
+ UINT16 format; /* Format identifier--format = 1 */
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of subtable */
@@ -753,17 +750,8 @@ struct PairPosFormat2
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
TRACE_COLLECT_GLYPHS (this);
- (this+coverage).add_coverage (c->input);
-
- unsigned int count1 = class1Count;
- const ClassDef &klass1 = this+classDef1;
- for (unsigned int i = 0; i < count1; i++)
- klass1.add_class (c->input, i);
-
- unsigned int count2 = class2Count;
- const ClassDef &klass2 = this+classDef2;
- for (unsigned int i = 0; i < count2; i++)
- klass2.add_class (c->input, i);
+ if (unlikely (!(this+coverage).add_coverage (c->input))) return;
+ if (unlikely (!(this+classDef2).add_coverage (c->input))) return;
}
inline const Coverage &get_coverage (void) const
@@ -790,6 +778,7 @@ struct PairPosFormat2
unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint);
if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return_trace (false);
+ buffer->unsafe_to_break (buffer->idx, skippy_iter.idx + 1);
const Value *v = &values[record_len * (klass1 * class2Count + klass2)];
valueFormat1.apply_value (c, this, v, buffer->cur_pos());
valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]);
@@ -820,7 +809,7 @@ struct PairPosFormat2
}
protected:
- USHORT format; /* Format identifier--format = 2 */
+ UINT16 format; /* Format identifier--format = 2 */
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of subtable */
@@ -838,9 +827,9 @@ struct PairPosFormat2
classDef2; /* Offset to ClassDef table--from
* beginning of PairPos subtable--for
* the second glyph of the pair */
- USHORT class1Count; /* Number of classes in ClassDef1
+ UINT16 class1Count; /* Number of classes in ClassDef1
* table--includes Class0 */
- USHORT class2Count; /* Number of classes in ClassDef2
+ UINT16 class2Count; /* Number of classes in ClassDef2
* table--includes Class0 */
ValueRecord values; /* Matrix of value pairs:
* class1-major, class2-minor,
@@ -865,7 +854,7 @@ struct PairPos
protected:
union {
- USHORT format; /* Format identifier */
+ UINT16 format; /* Format identifier */
PairPosFormat1 format1;
PairPosFormat2 format2;
} u;
@@ -903,7 +892,7 @@ struct CursivePosFormat1
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
TRACE_COLLECT_GLYPHS (this);
- (this+coverage).add_coverage (c->input);
+ if (unlikely (!(this+coverage).add_coverage (c->input))) return;
}
inline const Coverage &get_coverage (void) const
@@ -929,6 +918,7 @@ struct CursivePosFormat1
unsigned int i = buffer->idx;
unsigned int j = skippy_iter.idx;
+ buffer->unsafe_to_break (i, j);
hb_position_t entry_x, entry_y, exit_x, exit_y;
(this+this_record.exitAnchor).get_anchor (c, buffer->info[i].codepoint, &exit_x, &exit_y);
(this+next_record.entryAnchor).get_anchor (c, buffer->info[j].codepoint, &entry_x, &entry_y);
@@ -1018,7 +1008,7 @@ struct CursivePosFormat1
}
protected:
- USHORT format; /* Format identifier--format = 1 */
+ UINT16 format; /* Format identifier--format = 1 */
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of subtable */
@@ -1044,7 +1034,7 @@ struct CursivePos
protected:
union {
- USHORT format; /* Format identifier */
+ UINT16 format; /* Format identifier */
CursivePosFormat1 format1;
} u;
};
@@ -1060,8 +1050,8 @@ struct MarkBasePosFormat1
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
TRACE_COLLECT_GLYPHS (this);
- (this+markCoverage).add_coverage (c->input);
- (this+baseCoverage).add_coverage (c->input);
+ if (unlikely (!(this+markCoverage).add_coverage (c->input))) return;
+ if (unlikely (!(this+baseCoverage).add_coverage (c->input))) return;
}
inline const Coverage &get_coverage (void) const
@@ -1083,7 +1073,9 @@ struct MarkBasePosFormat1
do {
if (!skippy_iter.prev ()) return_trace (false);
/* We only want to attach to the first of a MultipleSubst sequence. Reject others. */
- if (0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx])) break;
+ if (!_hb_glyph_info_multiplied (&buffer->info[skippy_iter.idx]) ||
+ 0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]))
+ break;
skippy_iter.reject ();
} while (1);
@@ -1107,14 +1099,14 @@ struct MarkBasePosFormat1
}
protected:
- USHORT format; /* Format identifier--format = 1 */
+ UINT16 format; /* Format identifier--format = 1 */
OffsetTo<Coverage>
markCoverage; /* Offset to MarkCoverage table--from
* beginning of MarkBasePos subtable */
OffsetTo<Coverage>
baseCoverage; /* Offset to BaseCoverage table--from
* beginning of MarkBasePos subtable */
- USHORT classCount; /* Number of classes defined for marks */
+ UINT16 classCount; /* Number of classes defined for marks */
OffsetTo<MarkArray>
markArray; /* Offset to MarkArray table--from
* beginning of MarkBasePos subtable */
@@ -1140,7 +1132,7 @@ struct MarkBasePos
protected:
union {
- USHORT format; /* Format identifier */
+ UINT16 format; /* Format identifier */
MarkBasePosFormat1 format1;
} u;
};
@@ -1161,8 +1153,8 @@ struct MarkLigPosFormat1
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
TRACE_COLLECT_GLYPHS (this);
- (this+markCoverage).add_coverage (c->input);
- (this+ligatureCoverage).add_coverage (c->input);
+ if (unlikely (!(this+markCoverage).add_coverage (c->input))) return;
+ if (unlikely (!(this+ligatureCoverage).add_coverage (c->input))) return;
}
inline const Coverage &get_coverage (void) const
@@ -1224,7 +1216,7 @@ struct MarkLigPosFormat1
}
protected:
- USHORT format; /* Format identifier--format = 1 */
+ UINT16 format; /* Format identifier--format = 1 */
OffsetTo<Coverage>
markCoverage; /* Offset to Mark Coverage table--from
* beginning of MarkLigPos subtable */
@@ -1232,7 +1224,7 @@ struct MarkLigPosFormat1
ligatureCoverage; /* Offset to Ligature Coverage
* table--from beginning of MarkLigPos
* subtable */
- USHORT classCount; /* Number of defined mark classes */
+ UINT16 classCount; /* Number of defined mark classes */
OffsetTo<MarkArray>
markArray; /* Offset to MarkArray table--from
* beginning of MarkLigPos subtable */
@@ -1258,7 +1250,7 @@ struct MarkLigPos
protected:
union {
- USHORT format; /* Format identifier */
+ UINT16 format; /* Format identifier */
MarkLigPosFormat1 format1;
} u;
};
@@ -1274,8 +1266,8 @@ struct MarkMarkPosFormat1
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
TRACE_COLLECT_GLYPHS (this);
- (this+mark1Coverage).add_coverage (c->input);
- (this+mark2Coverage).add_coverage (c->input);
+ if (unlikely (!(this+mark1Coverage).add_coverage (c->input))) return;
+ if (unlikely (!(this+mark2Coverage).add_coverage (c->input))) return;
}
inline const Coverage &get_coverage (void) const
@@ -1338,7 +1330,7 @@ struct MarkMarkPosFormat1
}
protected:
- USHORT format; /* Format identifier--format = 1 */
+ UINT16 format; /* Format identifier--format = 1 */
OffsetTo<Coverage>
mark1Coverage; /* Offset to Combining Mark1 Coverage
* table--from beginning of MarkMarkPos
@@ -1347,7 +1339,7 @@ struct MarkMarkPosFormat1
mark2Coverage; /* Offset to Combining Mark2 Coverage
* table--from beginning of MarkMarkPos
* subtable */
- USHORT classCount; /* Number of defined mark classes */
+ UINT16 classCount; /* Number of defined mark classes */
OffsetTo<MarkArray>
mark1Array; /* Offset to Mark1Array table--from
* beginning of MarkMarkPos subtable */
@@ -1373,7 +1365,7 @@ struct MarkMarkPos
protected:
union {
- USHORT format; /* Format identifier */
+ UINT16 format; /* Format identifier */
MarkMarkPosFormat1 format1;
} u;
};
@@ -1432,7 +1424,7 @@ struct PosLookupSubTable
protected:
union {
- USHORT sub_format;
+ UINT16 sub_format;
SinglePos single;
PairPos pair;
CursivePos cursive;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh
index 66fcb3f3af..0b09c4e4a1 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh
@@ -44,7 +44,7 @@ struct SingleSubstFormat1
for (iter.init (this+coverage); iter.more (); iter.next ())
{
/* TODO Switch to range-based API to work around malicious fonts.
- * https://github.com/behdad/harfbuzz/issues/363 */
+ * https://github.com/harfbuzz/harfbuzz/issues/363 */
hb_codepoint_t glyph_id = iter.get_glyph ();
if (c->glyphs->has (glyph_id))
c->glyphs->add ((glyph_id + deltaGlyphID) & 0xFFFFu);
@@ -54,13 +54,13 @@ struct SingleSubstFormat1
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
TRACE_COLLECT_GLYPHS (this);
+ if (unlikely (!(this+coverage).add_coverage (c->input))) return;
Coverage::Iter iter;
for (iter.init (this+coverage); iter.more (); iter.next ())
{
/* TODO Switch to range-based API to work around malicious fonts.
- * https://github.com/behdad/harfbuzz/issues/363 */
+ * https://github.com/harfbuzz/harfbuzz/issues/363 */
hb_codepoint_t glyph_id = iter.get_glyph ();
- c->input->add (glyph_id);
c->output->add ((glyph_id + deltaGlyphID) & 0xFFFFu);
}
}
@@ -110,11 +110,11 @@ struct SingleSubstFormat1
}
protected:
- USHORT format; /* Format identifier--format = 1 */
+ UINT16 format; /* Format identifier--format = 1 */
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of Substitution table */
- SHORT deltaGlyphID; /* Add to original GlyphID to get
+ INT16 deltaGlyphID; /* Add to original GlyphID to get
* substitute GlyphID */
public:
DEFINE_SIZE_STATIC (6);
@@ -130,7 +130,7 @@ struct SingleSubstFormat2
for (iter.init (this+coverage); iter.more (); iter.next ())
{
if (unlikely (iter.get_coverage () >= count))
- break; /* Work around malicious fonts. https://github.com/behdad/harfbuzz/issues/363 */
+ break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
if (c->glyphs->has (iter.get_glyph ()))
c->glyphs->add (substitute[iter.get_coverage ()]);
}
@@ -139,13 +139,13 @@ struct SingleSubstFormat2
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
TRACE_COLLECT_GLYPHS (this);
+ if (unlikely (!(this+coverage).add_coverage (c->input))) return;
Coverage::Iter iter;
unsigned int count = substitute.len;
for (iter.init (this+coverage); iter.more (); iter.next ())
{
if (unlikely (iter.get_coverage () >= count))
- break; /* Work around malicious fonts. https://github.com/behdad/harfbuzz/issues/363 */
- c->input->add (iter.get_glyph ());
+ break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
c->output->add (substitute[iter.get_coverage ()]);
}
}
@@ -195,7 +195,7 @@ struct SingleSubstFormat2
}
protected:
- USHORT format; /* Format identifier--format = 2 */
+ UINT16 format; /* Format identifier--format = 2 */
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of Substitution table */
@@ -249,7 +249,7 @@ struct SingleSubst
protected:
union {
- USHORT format; /* Format identifier */
+ UINT16 format; /* Format identifier */
SingleSubstFormat1 format1;
SingleSubstFormat2 format2;
} u;
@@ -269,9 +269,7 @@ struct Sequence
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
TRACE_COLLECT_GLYPHS (this);
- unsigned int count = substitute.len;
- for (unsigned int i = 0; i < count; i++)
- c->output->add (substitute[i]);
+ c->output->add_array (substitute.array, substitute.len);
}
inline bool apply (hb_apply_context_t *c) const
@@ -287,7 +285,7 @@ struct Sequence
return_trace (true);
}
/* Spec disallows this, but Uniscribe allows it.
- * https://github.com/behdad/harfbuzz/issues/253 */
+ * https://github.com/harfbuzz/harfbuzz/issues/253 */
else if (unlikely (count == 0))
{
c->buffer->delete_glyph ();
@@ -339,7 +337,7 @@ struct MultipleSubstFormat1
for (iter.init (this+coverage); iter.more (); iter.next ())
{
if (unlikely (iter.get_coverage () >= count))
- break; /* Work around malicious fonts. https://github.com/behdad/harfbuzz/issues/363 */
+ break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
if (c->glyphs->has (iter.get_glyph ()))
(this+sequence[iter.get_coverage ()]).closure (c);
}
@@ -348,7 +346,7 @@ struct MultipleSubstFormat1
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
TRACE_COLLECT_GLYPHS (this);
- (this+coverage).add_coverage (c->input);
+ if (unlikely (!(this+coverage).add_coverage (c->input))) return;
unsigned int count = sequence.len;
for (unsigned int i = 0; i < count; i++)
(this+sequence[i]).collect_glyphs (c);
@@ -400,7 +398,7 @@ struct MultipleSubstFormat1
}
protected:
- USHORT format; /* Format identifier--format = 1 */
+ UINT16 format; /* Format identifier--format = 1 */
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of Substitution table */
@@ -442,7 +440,7 @@ struct MultipleSubst
protected:
union {
- USHORT format; /* Format identifier */
+ UINT16 format; /* Format identifier */
MultipleSubstFormat1 format1;
} u;
};
@@ -461,7 +459,7 @@ struct AlternateSubstFormat1
for (iter.init (this+coverage); iter.more (); iter.next ())
{
if (unlikely (iter.get_coverage () >= count))
- break; /* Work around malicious fonts. https://github.com/behdad/harfbuzz/issues/363 */
+ break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
if (c->glyphs->has (iter.get_glyph ())) {
const AlternateSet &alt_set = this+alternateSet[iter.get_coverage ()];
unsigned int count = alt_set.len;
@@ -474,17 +472,15 @@ struct AlternateSubstFormat1
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
TRACE_COLLECT_GLYPHS (this);
+ if (unlikely (!(this+coverage).add_coverage (c->input))) return;
Coverage::Iter iter;
unsigned int count = alternateSet.len;
for (iter.init (this+coverage); iter.more (); iter.next ())
{
if (unlikely (iter.get_coverage () >= count))
- break; /* Work around malicious fonts. https://github.com/behdad/harfbuzz/issues/363 */
- c->input->add (iter.get_glyph ());
+ break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
const AlternateSet &alt_set = this+alternateSet[iter.get_coverage ()];
- unsigned int count = alt_set.len;
- for (unsigned int i = 0; i < count; i++)
- c->output->add (alt_set[i]);
+ c->output->add_array (alt_set.array, alt_set.len);
}
}
@@ -552,7 +548,7 @@ struct AlternateSubstFormat1
}
protected:
- USHORT format; /* Format identifier--format = 1 */
+ UINT16 format; /* Format identifier--format = 1 */
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of Substitution table */
@@ -594,7 +590,7 @@ struct AlternateSubst
protected:
union {
- USHORT format; /* Format identifier */
+ UINT16 format; /* Format identifier */
AlternateSubstFormat1 format1;
} u;
};
@@ -615,9 +611,7 @@ struct Ligature
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
TRACE_COLLECT_GLYPHS (this);
- unsigned int count = component.len;
- for (unsigned int i = 1; i < count; i++)
- c->input->add (component[i]);
+ c->input->add_array (component.array, component.len ? component.len - 1 : 0);
c->output->add (ligGlyph);
}
@@ -658,7 +652,7 @@ struct Ligature
if (likely (!match_input (c, count,
&component[1],
match_glyph,
- NULL,
+ nullptr,
&match_length,
match_positions,
&is_mark_ligature,
@@ -792,7 +786,7 @@ struct LigatureSubstFormat1
for (iter.init (this+coverage); iter.more (); iter.next ())
{
if (unlikely (iter.get_coverage () >= count))
- break; /* Work around malicious fonts. https://github.com/behdad/harfbuzz/issues/363 */
+ break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
if (c->glyphs->has (iter.get_glyph ()))
(this+ligatureSet[iter.get_coverage ()]).closure (c);
}
@@ -801,13 +795,13 @@ struct LigatureSubstFormat1
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
TRACE_COLLECT_GLYPHS (this);
+ if (unlikely (!(this+coverage).add_coverage (c->input))) return;
Coverage::Iter iter;
unsigned int count = ligatureSet.len;
for (iter.init (this+coverage); iter.more (); iter.next ())
{
if (unlikely (iter.get_coverage () >= count))
- break; /* Work around malicious fonts. https://github.com/behdad/harfbuzz/issues/363 */
- c->input->add (iter.get_glyph ());
+ break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
(this+ligatureSet[iter.get_coverage ()]).collect_glyphs (c);
}
}
@@ -868,7 +862,7 @@ struct LigatureSubstFormat1
}
protected:
- USHORT format; /* Format identifier--format = 1 */
+ UINT16 format; /* Format identifier--format = 1 */
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of Substitution table */
@@ -918,7 +912,7 @@ struct LigatureSubst
protected:
union {
- USHORT format; /* Format identifier */
+ UINT16 format; /* Format identifier */
LigatureSubstFormat1 format1;
} u;
};
@@ -961,7 +955,7 @@ struct ReverseChainSingleSubstFormat1
for (iter.init (this+coverage); iter.more (); iter.next ())
{
if (unlikely (iter.get_coverage () >= count))
- break; /* Work around malicious fonts. https://github.com/behdad/harfbuzz/issues/363 */
+ break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
if (c->glyphs->has (iter.get_glyph ()))
c->glyphs->add (substitute[iter.get_coverage ()]);
}
@@ -970,25 +964,22 @@ struct ReverseChainSingleSubstFormat1
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
TRACE_COLLECT_GLYPHS (this);
-
- const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+ if (unlikely (!(this+coverage).add_coverage (c->input))) return;
unsigned int count;
- (this+coverage).add_coverage (c->input);
-
count = backtrack.len;
for (unsigned int i = 0; i < count; i++)
- (this+backtrack[i]).add_coverage (c->before);
+ if (unlikely (!(this+backtrack[i]).add_coverage (c->before))) return;
+ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
count = lookahead.len;
for (unsigned int i = 0; i < count; i++)
- (this+lookahead[i]).add_coverage (c->after);
+ if (unlikely (!(this+lookahead[i]).add_coverage (c->after))) return;
const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
count = substitute.len;
- for (unsigned int i = 0; i < count; i++)
- c->output->add (substitute[i]);
+ c->output->add_array (substitute.array, substitute.len);
}
inline const Coverage &get_coverage (void) const
@@ -1014,14 +1005,17 @@ struct ReverseChainSingleSubstFormat1
const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
+ unsigned int start_index = 0, end_index = 0;
if (match_backtrack (c,
- backtrack.len, (USHORT *) backtrack.array,
- match_coverage, this) &&
+ backtrack.len, (UINT16 *) backtrack.array,
+ match_coverage, this,
+ &start_index) &&
match_lookahead (c,
- lookahead.len, (USHORT *) lookahead.array,
+ lookahead.len, (UINT16 *) lookahead.array,
match_coverage, this,
- 1))
+ 1, &end_index))
{
+ c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index);
c->replace_glyph_inplace (substitute[index]);
/* Note: We DON'T decrease buffer->idx. The main loop does it
* for us. This is useful for preventing surprises if someone
@@ -1045,7 +1039,7 @@ struct ReverseChainSingleSubstFormat1
}
protected:
- USHORT format; /* Format identifier--format = 1 */
+ UINT16 format; /* Format identifier--format = 1 */
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of table */
@@ -1079,7 +1073,7 @@ struct ReverseChainSingleSubst
protected:
union {
- USHORT format; /* Format identifier */
+ UINT16 format; /* Format identifier */
ReverseChainSingleSubstFormat1 format1;
} u;
};
@@ -1125,7 +1119,7 @@ struct SubstLookupSubTable
protected:
union {
- USHORT sub_format;
+ UINT16 sub_format;
SingleSubst single;
MultipleSubst multiple;
AlternateSubst alternate;
@@ -1277,9 +1271,11 @@ struct SubstLookup : Lookup
if (unlikely (get_type () == SubstLookupSubTable::Extension))
{
/* The spec says all subtables of an Extension lookup should
- * have the same type. This is specially important if one has
- * a reverse type! */
+ * have the same type, which shall not be the Extension type
+ * itself. This is specially important if one has a reverse type! */
unsigned int type = get_subtable (0).u.extension.get_type ();
+ if (unlikely (type == SubstLookupSubTable::Extension))
+ return_trace (false);
unsigned int count = get_subtable_count ();
for (unsigned int i = 1; i < count; i++)
if (get_subtable (i).u.extension.get_type () != type)
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh
index fd75c5425a..b08a59138e 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh
@@ -29,6 +29,8 @@
#ifndef HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH
#define HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH
+#include "hb-private.hh"
+#include "hb-debug.hh"
#include "hb-buffer-private.hh"
#include "hb-ot-layout-gdef-table.hh"
#include "hb-set-private.hh"
@@ -37,15 +39,6 @@
namespace OT {
-#ifndef HB_DEBUG_CLOSURE
-#define HB_DEBUG_CLOSURE (HB_DEBUG+0)
-#endif
-
-#define TRACE_CLOSURE(this) \
- hb_auto_trace_t<HB_DEBUG_CLOSURE, hb_void_t> trace \
- (&c->debug_depth, c->get_name (), this, HB_FUNC, \
- "");
-
struct hb_closure_context_t :
hb_dispatch_context_t<hb_closure_context_t, hb_void_t, HB_DEBUG_CLOSURE>
{
@@ -77,7 +70,7 @@ struct hb_closure_context_t :
unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) :
face (face_),
glyphs (glyphs_),
- recurse_func (NULL),
+ recurse_func (nullptr),
nesting_level_left (nesting_level_left_),
debug_depth (0) {}
@@ -85,16 +78,6 @@ struct hb_closure_context_t :
};
-
-#ifndef HB_DEBUG_WOULD_APPLY
-#define HB_DEBUG_WOULD_APPLY (HB_DEBUG+0)
-#endif
-
-#define TRACE_WOULD_APPLY(this) \
- hb_auto_trace_t<HB_DEBUG_WOULD_APPLY, bool> trace \
- (&c->debug_depth, c->get_name (), this, HB_FUNC, \
- "%d glyphs", c->len);
-
struct hb_would_apply_context_t :
hb_dispatch_context_t<hb_would_apply_context_t, bool, HB_DEBUG_WOULD_APPLY>
{
@@ -122,16 +105,6 @@ struct hb_would_apply_context_t :
};
-
-#ifndef HB_DEBUG_COLLECT_GLYPHS
-#define HB_DEBUG_COLLECT_GLYPHS (HB_DEBUG+0)
-#endif
-
-#define TRACE_COLLECT_GLYPHS(this) \
- hb_auto_trace_t<HB_DEBUG_COLLECT_GLYPHS, hb_void_t> trace \
- (&c->debug_depth, c->get_name (), this, HB_FUNC, \
- "");
-
struct hb_collect_glyphs_context_t :
hb_dispatch_context_t<hb_collect_glyphs_context_t, hb_void_t, HB_DEBUG_COLLECT_GLYPHS>
{
@@ -146,7 +119,7 @@ struct hb_collect_glyphs_context_t :
if (unlikely (nesting_level_left == 0 || !recurse_func))
return default_return_value ();
- /* Note that GPOS sets recurse_func to NULL already, so it doesn't get
+ /* Note that GPOS sets recurse_func to nullptr already, so it doesn't get
* past the previous check. For GSUB, we only want to collect the output
* glyphs in the recursion. If output is not requested, we can go home now.
*
@@ -160,7 +133,7 @@ struct hb_collect_glyphs_context_t :
return HB_VOID;
/* Return if new lookup was recursed to before. */
- if (recursed_lookups.has (lookup_index))
+ if (recursed_lookups->has (lookup_index))
return HB_VOID;
hb_set_t *old_before = before;
@@ -176,7 +149,7 @@ struct hb_collect_glyphs_context_t :
input = old_input;
after = old_after;
- recursed_lookups.add (lookup_index);
+ recursed_lookups->add (lookup_index);
return HB_VOID;
}
@@ -187,31 +160,31 @@ struct hb_collect_glyphs_context_t :
hb_set_t *after;
hb_set_t *output;
recurse_func_t recurse_func;
- hb_set_t recursed_lookups;
+ hb_set_t *recursed_lookups;
unsigned int nesting_level_left;
unsigned int debug_depth;
hb_collect_glyphs_context_t (hb_face_t *face_,
- hb_set_t *glyphs_before, /* OUT. May be NULL */
- hb_set_t *glyphs_input, /* OUT. May be NULL */
- hb_set_t *glyphs_after, /* OUT. May be NULL */
- hb_set_t *glyphs_output, /* OUT. May be NULL */
+ hb_set_t *glyphs_before, /* OUT. May be nullptr */
+ hb_set_t *glyphs_input, /* OUT. May be nullptr */
+ hb_set_t *glyphs_after, /* OUT. May be nullptr */
+ hb_set_t *glyphs_output, /* OUT. May be nullptr */
unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) :
face (face_),
before (glyphs_before ? glyphs_before : hb_set_get_empty ()),
input (glyphs_input ? glyphs_input : hb_set_get_empty ()),
after (glyphs_after ? glyphs_after : hb_set_get_empty ()),
output (glyphs_output ? glyphs_output : hb_set_get_empty ()),
- recurse_func (NULL),
- recursed_lookups (),
+ recurse_func (nullptr),
+ recursed_lookups (nullptr),
nesting_level_left (nesting_level_left_),
debug_depth (0)
{
- recursed_lookups.init ();
+ recursed_lookups = hb_set_create ();
}
~hb_collect_glyphs_context_t (void)
{
- recursed_lookups.fini ();
+ hb_set_destroy (recursed_lookups);
}
void set_recurse_func (recurse_func_t func) { recurse_func = func; }
@@ -219,10 +192,6 @@ struct hb_collect_glyphs_context_t :
-#ifndef HB_DEBUG_GET_COVERAGE
-#define HB_DEBUG_GET_COVERAGE (HB_DEBUG+0)
-#endif
-
/* XXX Can we remove this? */
template <typename set_t>
@@ -249,17 +218,6 @@ struct hb_add_coverage_context_t :
};
-
-#ifndef HB_DEBUG_APPLY
-#define HB_DEBUG_APPLY (HB_DEBUG+0)
-#endif
-
-#define TRACE_APPLY(this) \
- hb_auto_trace_t<HB_DEBUG_APPLY, bool> trace \
- (&c->debug_depth, c->get_name (), this, HB_FUNC, \
- "idx %d gid %u lookup %d", \
- c->buffer->idx, c->buffer->cur().codepoint, (int) c->lookup_index);
-
struct hb_apply_context_t :
hb_dispatch_context_t<hb_apply_context_t, bool, HB_DEBUG_APPLY>
{
@@ -273,10 +231,10 @@ struct hb_apply_context_t :
#define arg1(arg) (arg) /* Remove the macro to see why it's needed! */
syllable arg1(0),
#undef arg1
- match_func (NULL),
- match_data (NULL) {};
+ match_func (nullptr),
+ match_data (nullptr) {};
- typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, const void *data);
+ typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const UINT16 &value, const void *data);
inline void set_ignore_zwnj (bool ignore_zwnj_) { ignore_zwnj = ignore_zwnj_; }
inline void set_ignore_zwj (bool ignore_zwj_) { ignore_zwj = ignore_zwj_; }
@@ -294,7 +252,7 @@ struct hb_apply_context_t :
};
inline may_match_t may_match (const hb_glyph_info_t &info,
- const USHORT *glyph_data) const
+ const UINT16 *glyph_data) const
{
if (!(info.mask & mask) ||
(syllable && syllable != info.syllable ()))
@@ -319,7 +277,7 @@ struct hb_apply_context_t :
if (!c->check_glyph_property (&info, lookup_props))
return SKIP_YES;
- if (unlikely (_hb_glyph_info_is_default_ignorable_and_not_fvs (&info) &&
+ if (unlikely (_hb_glyph_info_is_default_ignorable_and_not_hidden (&info) &&
(ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) &&
(ignore_zwj || !_hb_glyph_info_is_zwj (&info))))
return SKIP_MAYBE;
@@ -342,13 +300,13 @@ struct hb_apply_context_t :
inline void init (hb_apply_context_t *c_, bool context_match = false)
{
c = c_;
- match_glyph_data = NULL,
- matcher.set_match_func (NULL, NULL);
+ match_glyph_data = nullptr;
+ matcher.set_match_func (nullptr, nullptr);
matcher.set_lookup_props (c->lookup_props);
/* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */
- matcher.set_ignore_zwnj (context_match || c->table_index == 1);
+ matcher.set_ignore_zwnj (c->table_index == 1 || (context_match && c->auto_zwnj));
/* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if asked to. */
- matcher.set_ignore_zwj (context_match || c->table_index == 1 || c->auto_zwj);
+ matcher.set_ignore_zwj (c->table_index == 1 || (context_match || c->auto_zwj));
matcher.set_mask (context_match ? -1 : c->lookup_mask);
}
inline void set_lookup_props (unsigned int lookup_props)
@@ -357,7 +315,7 @@ struct hb_apply_context_t :
}
inline void set_match_func (matcher_t::match_func_t match_func_,
const void *match_data_,
- const USHORT glyph_data[])
+ const UINT16 glyph_data[])
{
matcher.set_match_func (match_func_, match_data_);
match_glyph_data = glyph_data;
@@ -374,6 +332,13 @@ struct hb_apply_context_t :
inline void reject (void) { num_items++; match_glyph_data--; }
+ inline matcher_t::may_skip_t
+ may_skip (const hb_apply_context_t *c,
+ const hb_glyph_info_t &info) const
+ {
+ return matcher.may_skip (c, info);
+ }
+
inline bool next (void)
{
assert (num_items > 0);
@@ -433,7 +398,7 @@ struct hb_apply_context_t :
protected:
hb_apply_context_t *c;
matcher_t matcher;
- const USHORT *match_glyph_data;
+ const UINT16 *match_glyph_data;
unsigned int num_items;
unsigned int end;
@@ -448,7 +413,7 @@ struct hb_apply_context_t :
bool stop_sublookup_iteration (return_t r) const { return r; }
return_t recurse (unsigned int lookup_index)
{
- if (unlikely (nesting_level_left == 0 || !recurse_func))
+ if (unlikely (nesting_level_left == 0 || !recurse_func || buffer->max_ops-- <= 0))
return default_return_value ();
nesting_level_left--;
@@ -457,45 +422,50 @@ struct hb_apply_context_t :
return ret;
}
- unsigned int table_index; /* GSUB/GPOS */
+ skipping_iterator_t iter_input, iter_context;
+
hb_font_t *font;
hb_face_t *face;
hb_buffer_t *buffer;
- hb_direction_t direction;
- hb_mask_t lookup_mask;
- bool auto_zwj;
recurse_func_t recurse_func;
- unsigned int nesting_level_left;
- unsigned int lookup_props;
const GDEF &gdef;
- bool has_glyph_classes;
const VariationStore &var_store;
- skipping_iterator_t iter_input, iter_context;
+
+ hb_direction_t direction;
+ hb_mask_t lookup_mask;
+ unsigned int table_index; /* GSUB/GPOS */
unsigned int lookup_index;
+ unsigned int lookup_props;
+ unsigned int nesting_level_left;
unsigned int debug_depth;
+ bool auto_zwnj;
+ bool auto_zwj;
+ bool has_glyph_classes;
+
hb_apply_context_t (unsigned int table_index_,
hb_font_t *font_,
hb_buffer_t *buffer_) :
- table_index (table_index_),
+ iter_input (), iter_context (),
font (font_), face (font->face), buffer (buffer_),
- direction (buffer_->props.direction),
- lookup_mask (1),
- auto_zwj (true),
- recurse_func (NULL),
- nesting_level_left (HB_MAX_NESTING_LEVEL),
- lookup_props (0),
+ recurse_func (nullptr),
gdef (*hb_ot_layout_from_face (face)->gdef),
- has_glyph_classes (gdef.has_glyph_classes ()),
var_store (gdef.get_var_store ()),
- iter_input (),
- iter_context (),
+ direction (buffer_->props.direction),
+ lookup_mask (1),
+ table_index (table_index_),
lookup_index ((unsigned int) -1),
- debug_depth (0) {}
+ lookup_props (0),
+ nesting_level_left (HB_MAX_NESTING_LEVEL),
+ debug_depth (0),
+ auto_zwnj (true),
+ auto_zwj (true),
+ has_glyph_classes (gdef.has_glyph_classes ()) {}
inline void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; }
inline void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; }
+ inline void set_auto_zwnj (bool auto_zwnj_) { auto_zwnj = auto_zwnj_; }
inline void set_recurse_func (recurse_func_t func) { recurse_func = func; }
inline void set_lookup_index (unsigned int lookup_index_) { lookup_index = lookup_index_; }
inline void set_lookup_props (unsigned int lookup_props_)
@@ -598,9 +568,9 @@ struct hb_apply_context_t :
-typedef bool (*intersects_func_t) (hb_set_t *glyphs, const USHORT &value, const void *data);
-typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, const USHORT &value, const void *data);
-typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, const void *data);
+typedef bool (*intersects_func_t) (hb_set_t *glyphs, const UINT16 &value, const void *data);
+typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, const UINT16 &value, const void *data);
+typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const UINT16 &value, const void *data);
struct ContextClosureFuncs
{
@@ -616,16 +586,16 @@ struct ContextApplyFuncs
};
-static inline bool intersects_glyph (hb_set_t *glyphs, const USHORT &value, const void *data HB_UNUSED)
+static inline bool intersects_glyph (hb_set_t *glyphs, const UINT16 &value, const void *data HB_UNUSED)
{
return glyphs->has (value);
}
-static inline bool intersects_class (hb_set_t *glyphs, const USHORT &value, const void *data)
+static inline bool intersects_class (hb_set_t *glyphs, const UINT16 &value, const void *data)
{
const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
return class_def.intersects_class (glyphs, value);
}
-static inline bool intersects_coverage (hb_set_t *glyphs, const USHORT &value, const void *data)
+static inline bool intersects_coverage (hb_set_t *glyphs, const UINT16 &value, const void *data)
{
const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value;
return (data+coverage).intersects (glyphs);
@@ -633,7 +603,7 @@ static inline bool intersects_coverage (hb_set_t *glyphs, const USHORT &value, c
static inline bool intersects_array (hb_closure_context_t *c,
unsigned int count,
- const USHORT values[],
+ const UINT16 values[],
intersects_func_t intersects_func,
const void *intersects_data)
{
@@ -644,16 +614,16 @@ static inline bool intersects_array (hb_closure_context_t *c,
}
-static inline void collect_glyph (hb_set_t *glyphs, const USHORT &value, const void *data HB_UNUSED)
+static inline void collect_glyph (hb_set_t *glyphs, const UINT16 &value, const void *data HB_UNUSED)
{
glyphs->add (value);
}
-static inline void collect_class (hb_set_t *glyphs, const USHORT &value, const void *data)
+static inline void collect_class (hb_set_t *glyphs, const UINT16 &value, const void *data)
{
const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
class_def.add_class (glyphs, value);
}
-static inline void collect_coverage (hb_set_t *glyphs, const USHORT &value, const void *data)
+static inline void collect_coverage (hb_set_t *glyphs, const UINT16 &value, const void *data)
{
const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value;
(data+coverage).add_coverage (glyphs);
@@ -661,7 +631,7 @@ static inline void collect_coverage (hb_set_t *glyphs, const USHORT &value, cons
static inline void collect_array (hb_collect_glyphs_context_t *c HB_UNUSED,
hb_set_t *glyphs,
unsigned int count,
- const USHORT values[],
+ const UINT16 values[],
collect_glyphs_func_t collect_func,
const void *collect_data)
{
@@ -670,16 +640,16 @@ static inline void collect_array (hb_collect_glyphs_context_t *c HB_UNUSED,
}
-static inline bool match_glyph (hb_codepoint_t glyph_id, const USHORT &value, const void *data HB_UNUSED)
+static inline bool match_glyph (hb_codepoint_t glyph_id, const UINT16 &value, const void *data HB_UNUSED)
{
return glyph_id == value;
}
-static inline bool match_class (hb_codepoint_t glyph_id, const USHORT &value, const void *data)
+static inline bool match_class (hb_codepoint_t glyph_id, const UINT16 &value, const void *data)
{
const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
return class_def.get_class (glyph_id) == value;
}
-static inline bool match_coverage (hb_codepoint_t glyph_id, const USHORT &value, const void *data)
+static inline bool match_coverage (hb_codepoint_t glyph_id, const UINT16 &value, const void *data)
{
const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value;
return (data+coverage).get_coverage (glyph_id) != NOT_COVERED;
@@ -687,7 +657,7 @@ static inline bool match_coverage (hb_codepoint_t glyph_id, const USHORT &value,
static inline bool would_match_input (hb_would_apply_context_t *c,
unsigned int count, /* Including the first glyph (not matched) */
- const USHORT input[], /* Array of input values--start with second glyph */
+ const UINT16 input[], /* Array of input values--start with second glyph */
match_func_t match_func,
const void *match_data)
{
@@ -702,15 +672,15 @@ static inline bool would_match_input (hb_would_apply_context_t *c,
}
static inline bool match_input (hb_apply_context_t *c,
unsigned int count, /* Including the first glyph (not matched) */
- const USHORT input[], /* Array of input values--start with second glyph */
+ const UINT16 input[], /* Array of input values--start with second glyph */
match_func_t match_func,
const void *match_data,
unsigned int *end_offset,
unsigned int match_positions[HB_MAX_CONTEXT_LENGTH],
- bool *p_is_mark_ligature = NULL,
- unsigned int *p_total_component_count = NULL)
+ bool *p_is_mark_ligature = nullptr,
+ unsigned int *p_total_component_count = nullptr)
{
- TRACE_APPLY (NULL);
+ TRACE_APPLY (nullptr);
if (unlikely (count > HB_MAX_CONTEXT_LENGTH)) return_trace (false);
@@ -731,11 +701,17 @@ static inline bool match_input (hb_apply_context_t *c,
* - Ligatures cannot be formed across glyphs attached to different components
* of previous ligatures. Eg. the sequence is LAM,SHADDA,LAM,FATHA,HEH, and
* LAM,LAM,HEH form a ligature, leaving SHADDA,FATHA next to eachother.
- * However, it would be wrong to ligate that SHADDA,FATHA sequence.o
- * There is an exception to this: If a ligature tries ligating with marks that
- * belong to it itself, go ahead, assuming that the font designer knows what
- * they are doing (otherwise it can break Indic stuff when a matra wants to
- * ligate with a conjunct...)
+ * However, it would be wrong to ligate that SHADDA,FATHA sequence.
+ * There are a couple of exceptions to this:
+ *
+ * o If a ligature tries ligating with marks that belong to it itself, go ahead,
+ * assuming that the font designer knows what they are doing (otherwise it can
+ * break Indic stuff when a matra wants to ligate with a conjunct,
+ *
+ * o If two marks want to ligate and they belong to different components of the
+ * same ligature glyph, and said ligature glyph is to be ignored according to
+ * mark-filtering rules, then allow.
+ * https://github.com/harfbuzz/harfbuzz/issues/545
*/
bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->cur());
@@ -746,6 +722,12 @@ static inline bool match_input (hb_apply_context_t *c,
unsigned int first_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
unsigned int first_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
+ enum {
+ LIGBASE_NOT_CHECKED,
+ LIGBASE_MAY_NOT_SKIP,
+ LIGBASE_MAY_SKIP
+ } ligbase = LIGBASE_NOT_CHECKED;
+
match_positions[0] = buffer->idx;
for (unsigned int i = 1; i < count; i++)
{
@@ -756,13 +738,43 @@ static inline bool match_input (hb_apply_context_t *c,
unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx]);
unsigned int this_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]);
- if (first_lig_id && first_lig_comp) {
+ if (first_lig_id && first_lig_comp)
+ {
/* If first component was attached to a previous ligature component,
* all subsequent components should be attached to the same ligature
- * component, otherwise we shouldn't ligate them. */
+ * component, otherwise we shouldn't ligate them... */
if (first_lig_id != this_lig_id || first_lig_comp != this_lig_comp)
- return_trace (false);
- } else {
+ {
+ /* ...unless, we are attached to a base ligature and that base
+ * ligature is ignorable. */
+ if (ligbase == LIGBASE_NOT_CHECKED)
+ {
+ bool found = false;
+ const hb_glyph_info_t *out = buffer->out_info;
+ unsigned int j = buffer->out_len;
+ while (j && _hb_glyph_info_get_lig_id (&out[j - 1]) == first_lig_id)
+ {
+ if (_hb_glyph_info_get_lig_comp (&out[j - 1]) == 0)
+ {
+ j--;
+ found = true;
+ break;
+ }
+ j--;
+ }
+
+ if (found && skippy_iter.may_skip (c, out[j]) == hb_apply_context_t::matcher_t::SKIP_YES)
+ ligbase = LIGBASE_MAY_SKIP;
+ else
+ ligbase = LIGBASE_MAY_NOT_SKIP;
+ }
+
+ if (ligbase == LIGBASE_MAY_NOT_SKIP)
+ return_trace (false);
+ }
+ }
+ else
+ {
/* If first component was NOT attached to a previous ligature component,
* all subsequent components should also NOT be attached to any ligature
* component, unless they are attached to the first component itself! */
@@ -792,7 +804,7 @@ static inline bool ligate_input (hb_apply_context_t *c,
bool is_mark_ligature,
unsigned int total_component_count)
{
- TRACE_APPLY (NULL);
+ TRACE_APPLY (nullptr);
hb_buffer_t *buffer = c->buffer;
@@ -884,11 +896,12 @@ static inline bool ligate_input (hb_apply_context_t *c,
static inline bool match_backtrack (hb_apply_context_t *c,
unsigned int count,
- const USHORT backtrack[],
+ const UINT16 backtrack[],
match_func_t match_func,
- const void *match_data)
+ const void *match_data,
+ unsigned int *match_start)
{
- TRACE_APPLY (NULL);
+ TRACE_APPLY (nullptr);
hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context;
skippy_iter.reset (c->buffer->backtrack_len (), count);
@@ -898,17 +911,20 @@ static inline bool match_backtrack (hb_apply_context_t *c,
if (!skippy_iter.prev ())
return_trace (false);
+ *match_start = skippy_iter.idx;
+
return_trace (true);
}
static inline bool match_lookahead (hb_apply_context_t *c,
unsigned int count,
- const USHORT lookahead[],
+ const UINT16 lookahead[],
match_func_t match_func,
const void *match_data,
- unsigned int offset)
+ unsigned int offset,
+ unsigned int *end_index)
{
- TRACE_APPLY (NULL);
+ TRACE_APPLY (nullptr);
hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context;
skippy_iter.reset (c->buffer->idx + offset - 1, count);
@@ -918,6 +934,8 @@ static inline bool match_lookahead (hb_apply_context_t *c,
if (!skippy_iter.next ())
return_trace (false);
+ *end_index = skippy_iter.idx + 1;
+
return_trace (true);
}
@@ -931,9 +949,9 @@ struct LookupRecord
return_trace (c->check_struct (this));
}
- USHORT sequenceIndex; /* Index into current glyph
+ UINT16 sequenceIndex; /* Index into current glyph
* sequence--first glyph = 0 */
- USHORT lookupListIndex; /* Lookup to apply to that
+ UINT16 lookupListIndex; /* Lookup to apply to that
* position--zero--based */
public:
DEFINE_SIZE_STATIC (4);
@@ -956,10 +974,10 @@ static inline bool apply_lookup (hb_apply_context_t *c,
const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */
unsigned int match_length)
{
- TRACE_APPLY (NULL);
+ TRACE_APPLY (nullptr);
hb_buffer_t *buffer = c->buffer;
- unsigned int end;
+ int end;
/* All positions are distance from beginning of *output* buffer.
* Adjust. */
@@ -984,7 +1002,11 @@ static inline bool apply_lookup (hb_apply_context_t *c,
if (idx == 0 && lookupRecord[i].lookupListIndex == c->lookup_index)
continue;
- buffer->move_to (match_positions[idx]);
+ if (unlikely (!buffer->move_to (match_positions[idx])))
+ break;
+
+ if (unlikely (buffer->max_ops <= 0))
+ break;
unsigned int orig_len = buffer->backtrack_len () + buffer->lookahead_len ();
if (!c->recurse (lookupRecord[i].lookupListIndex))
@@ -996,10 +1018,32 @@ static inline bool apply_lookup (hb_apply_context_t *c,
if (!delta)
continue;
- /* Recursed lookup changed buffer len. Adjust. */
+ /* Recursed lookup changed buffer len. Adjust.
+ *
+ * TODO:
+ *
+ * Right now, if buffer length increased by n, we assume n new glyphs
+ * were added right after the current position, and if buffer length
+ * was decreased by n, we assume n match positions after the current
+ * one where removed. The former (buffer length increased) case is
+ * fine, but the decrease case can be improved in at least two ways,
+ * both of which are significant:
+ *
+ * - If recursed-to lookup is MultipleSubst and buffer length
+ * decreased, then it's current match position that was deleted,
+ * NOT the one after it.
+ *
+ * - If buffer length was decreased by n, it does not necessarily
+ * mean that n match positions where removed, as there might
+ * have been marks and default-ignorables in the sequence. We
+ * should instead drop match positions between current-position
+ * and current-position + n instead.
+ *
+ * It should be possible to construct tests for both of these cases.
+ */
- end = int (end) + delta;
- if (end <= match_positions[idx])
+ end += delta;
+ if (end <= int (match_positions[idx]))
{
/* End might end up being smaller than match_positions[idx] if the recursed
* lookup ended up removing many items, more than we have had matched.
@@ -1068,7 +1112,7 @@ struct ContextApplyLookupContext
static inline void context_closure_lookup (hb_closure_context_t *c,
unsigned int inputCount, /* Including the first glyph (not matched) */
- const USHORT input[], /* Array of input values--start with second glyph */
+ const UINT16 input[], /* Array of input values--start with second glyph */
unsigned int lookupCount,
const LookupRecord lookupRecord[],
ContextClosureLookupContext &lookup_context)
@@ -1082,7 +1126,7 @@ static inline void context_closure_lookup (hb_closure_context_t *c,
static inline void context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c,
unsigned int inputCount, /* Including the first glyph (not matched) */
- const USHORT input[], /* Array of input values--start with second glyph */
+ const UINT16 input[], /* Array of input values--start with second glyph */
unsigned int lookupCount,
const LookupRecord lookupRecord[],
ContextCollectGlyphsLookupContext &lookup_context)
@@ -1096,7 +1140,7 @@ static inline void context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c
static inline bool context_would_apply_lookup (hb_would_apply_context_t *c,
unsigned int inputCount, /* Including the first glyph (not matched) */
- const USHORT input[], /* Array of input values--start with second glyph */
+ const UINT16 input[], /* Array of input values--start with second glyph */
unsigned int lookupCount HB_UNUSED,
const LookupRecord lookupRecord[] HB_UNUSED,
ContextApplyLookupContext &lookup_context)
@@ -1107,7 +1151,7 @@ static inline bool context_would_apply_lookup (hb_would_apply_context_t *c,
}
static inline bool context_apply_lookup (hb_apply_context_t *c,
unsigned int inputCount, /* Including the first glyph (not matched) */
- const USHORT input[], /* Array of input values--start with second glyph */
+ const UINT16 input[], /* Array of input values--start with second glyph */
unsigned int lookupCount,
const LookupRecord lookupRecord[],
ContextApplyLookupContext &lookup_context)
@@ -1118,10 +1162,11 @@ static inline bool context_apply_lookup (hb_apply_context_t *c,
inputCount, input,
lookup_context.funcs.match, lookup_context.match_data,
&match_length, match_positions)
- && apply_lookup (c,
+ && (c->buffer->unsafe_to_break (c->buffer->idx, c->buffer->idx + match_length),
+ apply_lookup (c,
inputCount, match_positions,
lookupCount, lookupRecord,
- match_length);
+ match_length));
}
struct Rule
@@ -1164,19 +1209,19 @@ struct Rule
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
- return inputCount.sanitize (c)
- && lookupCount.sanitize (c)
- && c->check_range (inputZ,
- inputZ[0].static_size * inputCount
- + lookupRecordX[0].static_size * lookupCount);
+ return_trace (inputCount.sanitize (c) &&
+ lookupCount.sanitize (c) &&
+ c->check_range (inputZ,
+ inputZ[0].static_size * inputCount +
+ lookupRecordX[0].static_size * lookupCount));
}
protected:
- USHORT inputCount; /* Total number of glyphs in input
+ UINT16 inputCount; /* Total number of glyphs in input
* glyph sequence--includes the first
* glyph */
- USHORT lookupCount; /* Number of LookupRecords */
- USHORT inputZ[VAR]; /* Array of match inputs--start with
+ UINT16 lookupCount; /* Number of LookupRecords */
+ UINT16 inputZ[VAR]; /* Array of match inputs--start with
* second glyph */
LookupRecord lookupRecordX[VAR]; /* Array of LookupRecords--in
* design order */
@@ -1251,7 +1296,7 @@ struct ContextFormat1
struct ContextClosureLookupContext lookup_context = {
{intersects_glyph},
- NULL
+ nullptr
};
unsigned int count = ruleSet.len;
@@ -1269,7 +1314,7 @@ struct ContextFormat1
struct ContextCollectGlyphsLookupContext lookup_context = {
{collect_glyph},
- NULL
+ nullptr
};
unsigned int count = ruleSet.len;
@@ -1284,7 +1329,7 @@ struct ContextFormat1
const RuleSet &rule_set = this+ruleSet[(this+coverage).get_coverage (c->glyphs[0])];
struct ContextApplyLookupContext lookup_context = {
{match_glyph},
- NULL
+ nullptr
};
return_trace (rule_set.would_apply (c, lookup_context));
}
@@ -1304,7 +1349,7 @@ struct ContextFormat1
const RuleSet &rule_set = this+ruleSet[index];
struct ContextApplyLookupContext lookup_context = {
{match_glyph},
- NULL
+ nullptr
};
return_trace (rule_set.apply (c, lookup_context));
}
@@ -1316,7 +1361,7 @@ struct ContextFormat1
}
protected:
- USHORT format; /* Format identifier--format = 1 */
+ UINT16 format; /* Format identifier--format = 1 */
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of table */
@@ -1409,7 +1454,7 @@ struct ContextFormat2
}
protected:
- USHORT format; /* Format identifier--format = 2 */
+ UINT16 format; /* Format identifier--format = 2 */
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of table */
@@ -1438,7 +1483,7 @@ struct ContextFormat3
this
};
context_closure_lookup (c,
- glyphCount, (const USHORT *) (coverageZ + 1),
+ glyphCount, (const UINT16 *) (coverageZ + 1),
lookupCount, lookupRecord,
lookup_context);
}
@@ -1455,7 +1500,7 @@ struct ContextFormat3
};
context_collect_glyphs_lookup (c,
- glyphCount, (const USHORT *) (coverageZ + 1),
+ glyphCount, (const UINT16 *) (coverageZ + 1),
lookupCount, lookupRecord,
lookup_context);
}
@@ -1469,7 +1514,7 @@ struct ContextFormat3
{match_coverage},
this
};
- return_trace (context_would_apply_lookup (c, glyphCount, (const USHORT *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context));
+ return_trace (context_would_apply_lookup (c, glyphCount, (const UINT16 *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context));
}
inline const Coverage &get_coverage (void) const
@@ -1488,7 +1533,7 @@ struct ContextFormat3
{match_coverage},
this
};
- return_trace (context_apply_lookup (c, glyphCount, (const USHORT *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context));
+ return_trace (context_apply_lookup (c, glyphCount, (const UINT16 *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context));
}
inline bool sanitize (hb_sanitize_context_t *c) const
@@ -1505,10 +1550,10 @@ struct ContextFormat3
}
protected:
- USHORT format; /* Format identifier--format = 3 */
- USHORT glyphCount; /* Number of glyphs in the input glyph
+ UINT16 format; /* Format identifier--format = 3 */
+ UINT16 glyphCount; /* Number of glyphs in the input glyph
* sequence */
- USHORT lookupCount; /* Number of LookupRecords */
+ UINT16 lookupCount; /* Number of LookupRecords */
OffsetTo<Coverage>
coverageZ[VAR]; /* Array of offsets to Coverage
* table in glyph sequence order */
@@ -1535,7 +1580,7 @@ struct Context
protected:
union {
- USHORT format; /* Format identifier */
+ UINT16 format; /* Format identifier */
ContextFormat1 format1;
ContextFormat2 format2;
ContextFormat3 format3;
@@ -1565,11 +1610,11 @@ struct ChainContextApplyLookupContext
static inline void chain_context_closure_lookup (hb_closure_context_t *c,
unsigned int backtrackCount,
- const USHORT backtrack[],
+ const UINT16 backtrack[],
unsigned int inputCount, /* Including the first glyph (not matched) */
- const USHORT input[], /* Array of input values--start with second glyph */
+ const UINT16 input[], /* Array of input values--start with second glyph */
unsigned int lookaheadCount,
- const USHORT lookahead[],
+ const UINT16 lookahead[],
unsigned int lookupCount,
const LookupRecord lookupRecord[],
ChainContextClosureLookupContext &lookup_context)
@@ -1589,11 +1634,11 @@ static inline void chain_context_closure_lookup (hb_closure_context_t *c,
static inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c,
unsigned int backtrackCount,
- const USHORT backtrack[],
+ const UINT16 backtrack[],
unsigned int inputCount, /* Including the first glyph (not matched) */
- const USHORT input[], /* Array of input values--start with second glyph */
+ const UINT16 input[], /* Array of input values--start with second glyph */
unsigned int lookaheadCount,
- const USHORT lookahead[],
+ const UINT16 lookahead[],
unsigned int lookupCount,
const LookupRecord lookupRecord[],
ChainContextCollectGlyphsLookupContext &lookup_context)
@@ -1613,11 +1658,11 @@ static inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_contex
static inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c,
unsigned int backtrackCount,
- const USHORT backtrack[] HB_UNUSED,
+ const UINT16 backtrack[] HB_UNUSED,
unsigned int inputCount, /* Including the first glyph (not matched) */
- const USHORT input[], /* Array of input values--start with second glyph */
+ const UINT16 input[], /* Array of input values--start with second glyph */
unsigned int lookaheadCount,
- const USHORT lookahead[] HB_UNUSED,
+ const UINT16 lookahead[] HB_UNUSED,
unsigned int lookupCount HB_UNUSED,
const LookupRecord lookupRecord[] HB_UNUSED,
ChainContextApplyLookupContext &lookup_context)
@@ -1630,16 +1675,16 @@ static inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c
static inline bool chain_context_apply_lookup (hb_apply_context_t *c,
unsigned int backtrackCount,
- const USHORT backtrack[],
+ const UINT16 backtrack[],
unsigned int inputCount, /* Including the first glyph (not matched) */
- const USHORT input[], /* Array of input values--start with second glyph */
+ const UINT16 input[], /* Array of input values--start with second glyph */
unsigned int lookaheadCount,
- const USHORT lookahead[],
+ const UINT16 lookahead[],
unsigned int lookupCount,
const LookupRecord lookupRecord[],
ChainContextApplyLookupContext &lookup_context)
{
- unsigned int match_length = 0;
+ unsigned int start_index = 0, match_length = 0, end_index = 0;
unsigned int match_positions[HB_MAX_CONTEXT_LENGTH];
return match_input (c,
inputCount, input,
@@ -1647,15 +1692,17 @@ static inline bool chain_context_apply_lookup (hb_apply_context_t *c,
&match_length, match_positions)
&& match_backtrack (c,
backtrackCount, backtrack,
- lookup_context.funcs.match, lookup_context.match_data[0])
+ lookup_context.funcs.match, lookup_context.match_data[0],
+ &start_index)
&& match_lookahead (c,
lookaheadCount, lookahead,
lookup_context.funcs.match, lookup_context.match_data[2],
- match_length)
- && apply_lookup (c,
+ match_length, &end_index)
+ && (c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index),
+ apply_lookup (c,
inputCount, match_positions,
lookupCount, lookupRecord,
- match_length);
+ match_length));
}
struct ChainRule
@@ -1663,8 +1710,8 @@ struct ChainRule
inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
{
TRACE_CLOSURE (this);
- const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
- const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
+ const HeadlessArrayOf<UINT16> &input = StructAfter<HeadlessArrayOf<UINT16> > (backtrack);
+ const ArrayOf<UINT16> &lookahead = StructAfter<ArrayOf<UINT16> > (input);
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
chain_context_closure_lookup (c,
backtrack.len, backtrack.array,
@@ -1677,8 +1724,8 @@ struct ChainRule
inline void collect_glyphs (hb_collect_glyphs_context_t *c, ChainContextCollectGlyphsLookupContext &lookup_context) const
{
TRACE_COLLECT_GLYPHS (this);
- const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
- const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
+ const HeadlessArrayOf<UINT16> &input = StructAfter<HeadlessArrayOf<UINT16> > (backtrack);
+ const ArrayOf<UINT16> &lookahead = StructAfter<ArrayOf<UINT16> > (input);
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
chain_context_collect_glyphs_lookup (c,
backtrack.len, backtrack.array,
@@ -1691,8 +1738,8 @@ struct ChainRule
inline bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
{
TRACE_WOULD_APPLY (this);
- const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
- const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
+ const HeadlessArrayOf<UINT16> &input = StructAfter<HeadlessArrayOf<UINT16> > (backtrack);
+ const ArrayOf<UINT16> &lookahead = StructAfter<ArrayOf<UINT16> > (input);
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
return_trace (chain_context_would_apply_lookup (c,
backtrack.len, backtrack.array,
@@ -1704,8 +1751,8 @@ struct ChainRule
inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
{
TRACE_APPLY (this);
- const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
- const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
+ const HeadlessArrayOf<UINT16> &input = StructAfter<HeadlessArrayOf<UINT16> > (backtrack);
+ const ArrayOf<UINT16> &lookahead = StructAfter<ArrayOf<UINT16> > (input);
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
return_trace (chain_context_apply_lookup (c,
backtrack.len, backtrack.array,
@@ -1718,23 +1765,23 @@ struct ChainRule
{
TRACE_SANITIZE (this);
if (!backtrack.sanitize (c)) return_trace (false);
- const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
+ const HeadlessArrayOf<UINT16> &input = StructAfter<HeadlessArrayOf<UINT16> > (backtrack);
if (!input.sanitize (c)) return_trace (false);
- const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
+ const ArrayOf<UINT16> &lookahead = StructAfter<ArrayOf<UINT16> > (input);
if (!lookahead.sanitize (c)) return_trace (false);
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
return_trace (lookup.sanitize (c));
}
protected:
- ArrayOf<USHORT>
+ ArrayOf<UINT16>
backtrack; /* Array of backtracking values
* (to be matched before the input
* sequence) */
- HeadlessArrayOf<USHORT>
+ HeadlessArrayOf<UINT16>
inputX; /* Array of input values (start with
* second glyph) */
- ArrayOf<USHORT>
+ ArrayOf<UINT16>
lookaheadX; /* Array of lookahead values's (to be
* matched after the input sequence) */
ArrayOf<LookupRecord>
@@ -1807,7 +1854,7 @@ struct ChainContextFormat1
struct ChainContextClosureLookupContext lookup_context = {
{intersects_glyph},
- {NULL, NULL, NULL}
+ {nullptr, nullptr, nullptr}
};
unsigned int count = ruleSet.len;
@@ -1825,7 +1872,7 @@ struct ChainContextFormat1
struct ChainContextCollectGlyphsLookupContext lookup_context = {
{collect_glyph},
- {NULL, NULL, NULL}
+ {nullptr, nullptr, nullptr}
};
unsigned int count = ruleSet.len;
@@ -1840,7 +1887,7 @@ struct ChainContextFormat1
const ChainRuleSet &rule_set = this+ruleSet[(this+coverage).get_coverage (c->glyphs[0])];
struct ChainContextApplyLookupContext lookup_context = {
{match_glyph},
- {NULL, NULL, NULL}
+ {nullptr, nullptr, nullptr}
};
return_trace (rule_set.would_apply (c, lookup_context));
}
@@ -1859,7 +1906,7 @@ struct ChainContextFormat1
const ChainRuleSet &rule_set = this+ruleSet[index];
struct ChainContextApplyLookupContext lookup_context = {
{match_glyph},
- {NULL, NULL, NULL}
+ {nullptr, nullptr, nullptr}
};
return_trace (rule_set.apply (c, lookup_context));
}
@@ -1871,7 +1918,7 @@ struct ChainContextFormat1
}
protected:
- USHORT format; /* Format identifier--format = 1 */
+ UINT16 format; /* Format identifier--format = 1 */
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of table */
@@ -1986,7 +2033,7 @@ struct ChainContextFormat2
}
protected:
- USHORT format; /* Format identifier--format = 2 */
+ UINT16 format; /* Format identifier--format = 2 */
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of table */
@@ -2026,9 +2073,9 @@ struct ChainContextFormat3
{this, this, this}
};
chain_context_closure_lookup (c,
- backtrack.len, (const USHORT *) backtrack.array,
- input.len, (const USHORT *) input.array + 1,
- lookahead.len, (const USHORT *) lookahead.array,
+ backtrack.len, (const UINT16 *) backtrack.array,
+ input.len, (const UINT16 *) input.array + 1,
+ lookahead.len, (const UINT16 *) lookahead.array,
lookup.len, lookup.array,
lookup_context);
}
@@ -2047,9 +2094,9 @@ struct ChainContextFormat3
{this, this, this}
};
chain_context_collect_glyphs_lookup (c,
- backtrack.len, (const USHORT *) backtrack.array,
- input.len, (const USHORT *) input.array + 1,
- lookahead.len, (const USHORT *) lookahead.array,
+ backtrack.len, (const UINT16 *) backtrack.array,
+ input.len, (const UINT16 *) input.array + 1,
+ lookahead.len, (const UINT16 *) lookahead.array,
lookup.len, lookup.array,
lookup_context);
}
@@ -2066,9 +2113,9 @@ struct ChainContextFormat3
{this, this, this}
};
return_trace (chain_context_would_apply_lookup (c,
- backtrack.len, (const USHORT *) backtrack.array,
- input.len, (const USHORT *) input.array + 1,
- lookahead.len, (const USHORT *) lookahead.array,
+ backtrack.len, (const UINT16 *) backtrack.array,
+ input.len, (const UINT16 *) input.array + 1,
+ lookahead.len, (const UINT16 *) lookahead.array,
lookup.len, lookup.array, lookup_context));
}
@@ -2093,9 +2140,9 @@ struct ChainContextFormat3
{this, this, this}
};
return_trace (chain_context_apply_lookup (c,
- backtrack.len, (const USHORT *) backtrack.array,
- input.len, (const USHORT *) input.array + 1,
- lookahead.len, (const USHORT *) lookahead.array,
+ backtrack.len, (const UINT16 *) backtrack.array,
+ input.len, (const UINT16 *) input.array + 1,
+ lookahead.len, (const UINT16 *) lookahead.array,
lookup.len, lookup.array, lookup_context));
}
@@ -2113,7 +2160,7 @@ struct ChainContextFormat3
}
protected:
- USHORT format; /* Format identifier--format = 3 */
+ UINT16 format; /* Format identifier--format = 3 */
OffsetArrayOf<Coverage>
backtrack; /* Array of coverage tables
* in backtracking sequence, in glyph
@@ -2150,7 +2197,7 @@ struct ChainContext
protected:
union {
- USHORT format; /* Format identifier */
+ UINT16 format; /* Format identifier */
ChainContextFormat1 format1;
ChainContextFormat2 format2;
ChainContextFormat3 format3;
@@ -2187,11 +2234,11 @@ struct ExtensionFormat1
}
protected:
- USHORT format; /* Format identifier. Set to 1. */
- USHORT extensionLookupType; /* Lookup type of subtable referenced
+ UINT16 format; /* Format identifier. Set to 1. */
+ UINT16 extensionLookupType; /* Lookup type of subtable referenced
* by ExtensionOffset (i.e. the
* extension subtable). */
- ULONG extensionOffset; /* Offset to the extension subtable,
+ UINT32 extensionOffset; /* Offset to the extension subtable,
* of lookup type subtable. */
public:
DEFINE_SIZE_STATIC (8);
@@ -2229,7 +2276,7 @@ struct Extension
protected:
union {
- USHORT format; /* Format identifier */
+ UINT16 format; /* Format identifier */
ExtensionFormat1<T> format1;
} u;
};
@@ -2241,9 +2288,6 @@ struct Extension
struct GSUBGPOS
{
- static const hb_tag_t GSUBTag = HB_OT_TAG_GSUB;
- static const hb_tag_t GPOSTag = HB_OT_TAG_GPOS;
-
inline unsigned int get_script_count (void) const
{ return (this+scriptList).len; }
inline const Tag& get_script_tag (unsigned int i) const
@@ -2313,7 +2357,7 @@ struct GSUBGPOS
featureList; /* FeatureList table */
OffsetTo<LookupList>
lookupList; /* LookupList table */
- OffsetTo<FeatureVariations, ULONG>
+ LOffsetTo<FeatureVariations>
featureVars; /* Offset to Feature Variations
table--from beginning of table
* (may be NULL). Introduced
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh
index c3068491be..adbaad64f3 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh
@@ -124,7 +124,7 @@ struct JstfPriority
struct JstfLangSys : OffsetListOf<JstfPriority>
{
inline bool sanitize (hb_sanitize_context_t *c,
- const Record<JstfLangSys>::sanitize_closure_t * = NULL) const
+ const Record<JstfLangSys>::sanitize_closure_t * = nullptr) const
{
TRACE_SANITIZE (this);
return_trace (OffsetListOf<JstfPriority>::sanitize (c));
@@ -165,7 +165,7 @@ struct JstfScript
inline const JstfLangSys& get_default_lang_sys (void) const { return this+defaultLangSys; }
inline bool sanitize (hb_sanitize_context_t *c,
- const Record<JstfScript>::sanitize_closure_t * = NULL) const
+ const Record<JstfScript>::sanitize_closure_t * = nullptr) const
{
TRACE_SANITIZE (this);
return_trace (extenderGlyphs.sanitize (c, this) &&
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh
index a4272de631..0f0926f890 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh
@@ -33,7 +33,8 @@
#include "hb-font-private.hh"
#include "hb-buffer-private.hh"
-#include "hb-set-private.hh"
+#include "hb-set-digest-private.hh"
+#include "hb-open-type-private.hh"
/* Private API corresponding to hb-ot-layout.h: */
@@ -125,6 +126,8 @@ namespace OT {
struct GSUB;
struct GPOS;
struct MATH;
+ struct fvar;
+ struct avar;
}
struct hb_ot_layout_lookup_accelerator_t
@@ -153,12 +156,15 @@ struct hb_ot_layout_t
hb_blob_t *gdef_blob;
hb_blob_t *gsub_blob;
hb_blob_t *gpos_blob;
- hb_blob_t *math_blob;
const struct OT::GDEF *gdef;
const struct OT::GSUB *gsub;
const struct OT::GPOS *gpos;
- const struct OT::MATH *math;
+
+ /* TODO Move the following out of this struct. */
+ OT::hb_lazy_table_loader_t<struct OT::MATH> math;
+ OT::hb_lazy_table_loader_t<struct OT::fvar> fvar;
+ OT::hb_lazy_table_loader_t<struct OT::avar> avar;
unsigned int gsub_lookup_count;
unsigned int gpos_lookup_count;
@@ -191,8 +197,7 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout);
#define syllable() var1.u8[3] /* GSUB/GPOS shaping boundaries */
-/* loop over syllables */
-
+/* Loop over syllables. Based on foreach_cluster(). */
#define foreach_syllable(buffer, start, end) \
for (unsigned int \
_count = buffer->len, \
@@ -221,7 +226,9 @@ _next_syllable (hb_buffer_t *buffer, unsigned int start)
* - General_Category: 5 bits.
* - A bit each for:
* * Is it Default_Ignorable(); we have a modified Default_Ignorable().
- * * Whether it's one of the three Mongolian Free Variation Selectors.
+ * * Whether it's one of the three Mongolian Free Variation Selectors,
+ * CGJ, or other characters that are hidden but should not be ignored
+ * like most other Default_Ignorable()s do during matching.
* * One free bit right now.
*
* The high-byte has different meanings, switched by the Gen-Cat:
@@ -234,7 +241,8 @@ _next_syllable (hb_buffer_t *buffer, unsigned int start)
enum hb_unicode_props_flags_t {
UPROPS_MASK_GEN_CAT = 0x001Fu,
UPROPS_MASK_IGNORABLE = 0x0020u,
- UPROPS_MASK_FVS = 0x0040u, /* MONGOLIAN FREE VARIATION SELECTOR 1..3 */
+ UPROPS_MASK_HIDDEN = 0x0040u, /* MONGOLIAN FREE VARIATION SELECTOR 1..3,
+ * or TAG characters */
/* If GEN_CAT=FORMAT, top byte masks: */
UPROPS_MASK_Cf_ZWJ = 0x0100u,
@@ -258,16 +266,21 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer)
buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES;
props |= UPROPS_MASK_IGNORABLE;
if (u == 0x200Cu) props |= UPROPS_MASK_Cf_ZWNJ;
- if (u == 0x200Du) props |= UPROPS_MASK_Cf_ZWJ;
+ else if (u == 0x200Du) props |= UPROPS_MASK_Cf_ZWJ;
/* Mongolian Free Variation Selectors need to be remembered
* because although we need to hide them like default-ignorables,
* they need to non-ignorable during shaping. This is similar to
* what we do for joiners in Indic-like shapers, but since the
* FVSes are GC=Mn, we have use a separate bit to remember them.
* Fixes:
- * https://github.com/behdad/harfbuzz/issues/234
- */
- if (unlikely (hb_in_range (u, 0x180Bu, 0x180Du))) props |= UPROPS_MASK_FVS;
+ * https://github.com/harfbuzz/harfbuzz/issues/234 */
+ else if (unlikely (hb_in_range (u, 0x180Bu, 0x180Du))) props |= UPROPS_MASK_HIDDEN;
+ /* TAG characters need similar treatment. Fixes:
+ * https://github.com/harfbuzz/harfbuzz/issues/463 */
+ else if (unlikely (hb_in_range (u, 0xE0020u, 0xE007Fu))) props |= UPROPS_MASK_HIDDEN;
+ /* COMBINING GRAPHEME JOINER should not be skipped; at least some times.
+ * https://github.com/harfbuzz/harfbuzz/issues/554 */
+ else if (unlikely (u == 0x034Fu)) props |= UPROPS_MASK_HIDDEN;
}
else if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_NON_ENCLOSING_MARK_OR_MODIFIER_SYMBOL (gen_cat)))
{
@@ -292,7 +305,7 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer)
/* Recategorize emoji skin-tone modifiers as Unicode mark, so they
* behave correctly in non-native directionality. They originally
* are MODIFIER_SYMBOL. Fixes:
- * https://github.com/behdad/harfbuzz/issues/169
+ * https://github.com/harfbuzz/harfbuzz/issues/169
*/
if (unlikely (hb_in_range (u, 0x1F3FBu, 0x1F3FFu)))
{
@@ -337,6 +350,8 @@ _hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info)
return _hb_glyph_info_is_unicode_mark (info) ? info->unicode_props()>>8 : 0;
}
+#define info_cc(info) (_hb_glyph_info_get_modified_combining_class (&(info)))
+
static inline bool
_hb_glyph_info_is_unicode_space (const hb_glyph_info_t *info)
{
@@ -367,9 +382,9 @@ _hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info)
!_hb_glyph_info_ligated (info);
}
static inline hb_bool_t
-_hb_glyph_info_is_default_ignorable_and_not_fvs (const hb_glyph_info_t *info)
+_hb_glyph_info_is_default_ignorable_and_not_hidden (const hb_glyph_info_t *info)
{
- return ((info->unicode_props() & (UPROPS_MASK_IGNORABLE|UPROPS_MASK_FVS))
+ return ((info->unicode_props() & (UPROPS_MASK_IGNORABLE|UPROPS_MASK_HIDDEN))
== UPROPS_MASK_IGNORABLE) &&
!_hb_glyph_info_ligated (info);
}
@@ -617,5 +632,4 @@ _hb_buffer_assert_gsubgpos_vars (hb_buffer_t *buffer)
#undef lig_props
#undef glyph_props
-
#endif /* HB_OT_LAYOUT_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc
index 145ec76389..8845889827 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc
@@ -34,22 +34,21 @@
#include "hb-ot-layout-gdef-table.hh"
#include "hb-ot-layout-gsub-table.hh"
#include "hb-ot-layout-gpos-table.hh"
-#include "hb-ot-layout-jstf-table.hh"
+#include "hb-ot-layout-jstf-table.hh" // Just so we compile it; unused otherwise.
+#include "hb-ot-name-table.hh" // Just so we compile it; unused otherwise.
#include "hb-ot-map-private.hh"
-#include <stdlib.h>
-#include <string.h>
+const void * const OT::_hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {};
-HB_SHAPER_DATA_ENSURE_DECLARE(ot, face)
hb_ot_layout_t *
_hb_ot_layout_create (hb_face_t *face)
{
hb_ot_layout_t *layout = (hb_ot_layout_t *) calloc (1, sizeof (hb_ot_layout_t));
if (unlikely (!layout))
- return NULL;
+ return nullptr;
layout->gdef_blob = OT::Sanitizer<OT::GDEF>::sanitize (face->reference_table (HB_OT_TAG_GDEF));
layout->gdef = OT::Sanitizer<OT::GDEF>::lock_instance (layout->gdef_blob);
@@ -60,9 +59,9 @@ _hb_ot_layout_create (hb_face_t *face)
layout->gpos_blob = OT::Sanitizer<OT::GPOS>::sanitize (face->reference_table (HB_OT_TAG_GPOS));
layout->gpos = OT::Sanitizer<OT::GPOS>::lock_instance (layout->gpos_blob);
- /* The MATH table is rarely used, so only try and load it in _get_math. */
- layout->math_blob = NULL;
- layout->math = NULL;
+ layout->math.init (face);
+ layout->fvar.init (face);
+ layout->avar.init (face);
{
/*
@@ -106,14 +105,28 @@ _hb_ot_layout_create (hb_face_t *face)
|| (928 == gdef_len && 59332 == gpos_len && 23298 == gsub_len)
/* sha1sum:6d400781948517c3c0441ba42acb309584b73033 tahomabd.ttf from Windows 8.1 */
|| (940 == gdef_len && 60732 == gpos_len && 23310 == gsub_len)
+ /* tahoma.ttf v6.04 from Windows 8.1 x64, see https://bugzilla.mozilla.org/show_bug.cgi?id=1279925 */
+ || (964 == gdef_len && 60072 == gpos_len && 23836 == gsub_len)
+ /* tahomabd.ttf v6.04 from Windows 8.1 x64, see https://bugzilla.mozilla.org/show_bug.cgi?id=1279925 */
+ || (976 == gdef_len && 61456 == gpos_len && 23832 == gsub_len)
/* sha1sum:e55fa2dfe957a9f7ec26be516a0e30b0c925f846 tahoma.ttf from Windows 10 */
|| (994 == gdef_len && 60336 == gpos_len && 24474 == gsub_len)
/* sha1sum:7199385abb4c2cc81c83a151a7599b6368e92343 tahomabd.ttf from Windows 10 */
|| (1006 == gdef_len && 61740 == gpos_len && 24470 == gsub_len)
+ /* tahoma.ttf v6.91 from Windows 10 x64, see https://bugzilla.mozilla.org/show_bug.cgi?id=1279925 */
+ || (1006 == gdef_len && 61346 == gpos_len && 24576 == gsub_len)
+ /* tahomabd.ttf v6.91 from Windows 10 x64, see https://bugzilla.mozilla.org/show_bug.cgi?id=1279925 */
+ || (1018 == gdef_len && 62828 == gpos_len && 24572 == gsub_len)
+ /* sha1sum:b9c84d820c49850d3d27ec498be93955b82772b5 tahoma.ttf from Windows 10 AU */
+ || (1006 == gdef_len && 61352 == gpos_len && 24576 == gsub_len)
+ /* sha1sum:2bdfaab28174bdadd2f3d4200a30a7ae31db79d2 tahomabd.ttf from Windows 10 AU */
+ || (1018 == gdef_len && 62834 == gpos_len && 24572 == gsub_len)
/* sha1sum:b0d36cf5a2fbe746a3dd277bffc6756a820807a7 Tahoma.ttf from Mac OS X 10.9 */
|| (832 == gdef_len && 47162 == gpos_len && 7324 == gsub_len)
/* sha1sum:12fc4538e84d461771b30c18b5eb6bd434e30fba Tahoma Bold.ttf from Mac OS X 10.9 */
|| (844 == gdef_len && 45474 == gpos_len && 7302 == gsub_len)
+ /* sha1sum:eb8afadd28e9cf963e886b23a30b44ab4fd83acc himalaya.ttf from Windows 7 */
+ || (180 == gdef_len && 7254 == gpos_len && 13054 == gsub_len)
/* sha1sum:73da7f025b238a3f737aa1fde22577a6370f77b0 himalaya.ttf from Windows 8 */
|| (192 == gdef_len && 7254 == gpos_len && 12638 == gsub_len)
/* sha1sum:6e80fd1c0b059bbee49272401583160dc1e6a427 himalaya.ttf from Windows 8.1 */
@@ -124,6 +137,14 @@ _hb_ot_layout_create (hb_face_t *face)
/* 2c0c90c6f6087ffbfea76589c93113a9cbb0e75f cantarell-fonts-0.0.21/otf/Cantarell-Bold.otf */
/* 55461f5b853c6da88069ffcdf7f4dd3f8d7e3e6b cantarell-fonts-0.0.21/otf/Cantarell-Bold-Oblique.otf */
|| (188 == gdef_len && 3426 == gpos_len && 264 == gsub_len)
+ /* d125afa82a77a6475ac0e74e7c207914af84b37a padauk-2.80/Padauk.ttf RHEL 7.2 */
+ || (1058 == gdef_len && 11818 == gpos_len && 47032 == gsub_len)
+ /* 0f7b80437227b90a577cc078c0216160ae61b031 padauk-2.80/Padauk-Bold.ttf RHEL 7.2*/
+ || (1046 == gdef_len && 12600 == gpos_len && 47030 == gsub_len)
+ /* d3dde9aa0a6b7f8f6a89ef1002e9aaa11b882290 padauk-2.80/Padauk.ttf Ubuntu 16.04 */
+ || (1058 == gdef_len && 16770 == gpos_len && 71796 == gsub_len)
+ /* 5f3c98ccccae8a953be2d122c1b3a77fd805093f padauk-2.80/Padauk-Bold.ttf Ubuntu 16.04 */
+ || (1046 == gdef_len && 17862 == gpos_len && 71790 == gsub_len)
/* 6c93b63b64e8b2c93f5e824e78caca555dc887c7 padauk-2.80/Padauk-book.ttf */
|| (1046 == gdef_len && 17112 == gpos_len && 71788 == gsub_len)
/* d89b1664058359b8ec82e35d3531931125991fb9 padauk-2.80/Padauk-bookbold.ttf */
@@ -132,6 +153,9 @@ _hb_ot_layout_create (hb_face_t *face)
|| (1330 == gdef_len && 57938 == gpos_len && 109904 == gsub_len)
/* 91fcc10cf15e012d27571e075b3b4dfe31754a8a padauk-3.0/Padauk-bookbold.ttf */
|| (1330 == gdef_len && 58972 == gpos_len && 109904 == gsub_len)
+ /* sha1sum: c26e41d567ed821bed997e937bc0c41435689e85 Padauk.ttf
+ * "Padauk Regular" "Version 2.5", see https://crbug.com/681813 */
+ || (1004 == gdef_len && 14836 == gpos_len && 59092 == gsub_len)
)
{
/* Many versions of Tahoma have bad GDEF tables that incorrectly classify some spacing marks
@@ -156,7 +180,7 @@ _hb_ot_layout_create (hb_face_t *face)
(layout->gpos_lookup_count && !layout->gpos_accels)))
{
_hb_ot_layout_destroy (layout);
- return NULL;
+ return nullptr;
}
for (unsigned int i = 0; i < layout->gsub_lookup_count; i++)
@@ -181,7 +205,10 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout)
hb_blob_destroy (layout->gdef_blob);
hb_blob_destroy (layout->gsub_blob);
hb_blob_destroy (layout->gpos_blob);
- hb_blob_destroy (layout->math_blob);
+
+ layout->math.fini ();
+ layout->fvar.fini ();
+ layout->avar.fini ();
free (layout);
}
@@ -256,7 +283,7 @@ hb_ot_layout_get_ligature_carets (hb_font_t *font,
hb_codepoint_t glyph,
unsigned int start_offset,
unsigned int *caret_count /* IN/OUT */,
- int *caret_array /* OUT */)
+ hb_position_t *caret_array /* OUT */)
{
return _get_gdef (font->face).get_lig_carets (font, direction, glyph, start_offset, caret_count, caret_array);
}
@@ -298,7 +325,7 @@ hb_ot_layout_table_find_script (hb_face_t *face,
hb_tag_t script_tag,
unsigned int *script_index)
{
- ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX);
+ static_assert ((OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX), "");
const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
if (g.find_script_index (script_tag, script_index))
@@ -329,7 +356,7 @@ hb_ot_layout_table_choose_script (hb_face_t *face,
unsigned int *script_index,
hb_tag_t *chosen_script)
{
- ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX);
+ static_assert ((OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX), "");
const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
while (*script_tags)
@@ -388,7 +415,7 @@ hb_ot_layout_table_find_feature (hb_face_t *face,
hb_tag_t feature_tag,
unsigned int *feature_index)
{
- ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX);
+ static_assert ((OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX), "");
const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
unsigned int num_features = g.get_feature_count ();
@@ -425,7 +452,7 @@ hb_ot_layout_script_find_language (hb_face_t *face,
hb_tag_t language_tag,
unsigned int *language_index)
{
- ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX);
+ static_assert ((OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX), "");
const OT::Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index);
if (s.find_lang_sys_index (language_tag, language_index))
@@ -451,7 +478,7 @@ hb_ot_layout_language_get_required_feature_index (hb_face_t *face,
script_index,
language_index,
feature_index,
- NULL);
+ nullptr);
}
/**
@@ -504,7 +531,7 @@ hb_ot_layout_language_get_feature_tags (hb_face_t *face,
const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
- ASSERT_STATIC (sizeof (unsigned int) == sizeof (hb_tag_t));
+ static_assert ((sizeof (unsigned int) == sizeof (hb_tag_t)), "");
unsigned int ret = l.get_feature_indexes (start_offset, feature_count, (unsigned int *) feature_tags);
if (feature_tags) {
@@ -525,7 +552,7 @@ hb_ot_layout_language_find_feature (hb_face_t *face,
hb_tag_t feature_tag,
unsigned int *feature_index)
{
- ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX);
+ static_assert ((OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX), "");
const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
@@ -574,6 +601,7 @@ unsigned int
hb_ot_layout_table_get_lookup_count (hb_face_t *face,
hb_tag_t table_tag)
{
+ if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return 0;
switch (table_tag)
{
case HB_OT_TAG_GSUB:
@@ -629,7 +657,7 @@ _hb_ot_layout_collect_lookups_features (hb_face_t *face,
script_index,
language_index,
&required_feature_index,
- NULL))
+ nullptr))
_hb_ot_layout_collect_lookups_lookups (face,
table_tag,
required_feature_index,
@@ -698,7 +726,7 @@ _hb_ot_layout_collect_lookups_languages (hb_face_t *face,
unsigned int count = hb_ot_layout_script_get_language_tags (face,
table_tag,
script_index,
- 0, NULL, NULL);
+ 0, nullptr, nullptr);
for (unsigned int language_index = 0; language_index < count; language_index++)
_hb_ot_layout_collect_lookups_features (face,
table_tag,
@@ -745,7 +773,7 @@ hb_ot_layout_collect_lookups (hb_face_t *face,
/* All scripts */
unsigned int count = hb_ot_layout_table_get_script_tags (face,
table_tag,
- 0, NULL, NULL);
+ 0, nullptr, nullptr);
for (unsigned int script_index = 0; script_index < count; script_index++)
_hb_ot_layout_collect_lookups_languages (face,
table_tag,
@@ -782,10 +810,10 @@ void
hb_ot_layout_lookup_collect_glyphs (hb_face_t *face,
hb_tag_t table_tag,
unsigned int lookup_index,
- hb_set_t *glyphs_before, /* OUT. May be NULL */
- hb_set_t *glyphs_input, /* OUT. May be NULL */
- hb_set_t *glyphs_after, /* OUT. May be NULL */
- hb_set_t *glyphs_output /* OUT. May be NULL */)
+ hb_set_t *glyphs_before, /* OUT. May be nullptr */
+ hb_set_t *glyphs_input, /* OUT. May be nullptr */
+ hb_set_t *glyphs_after, /* OUT. May be nullptr */
+ hb_set_t *glyphs_output /* OUT. May be nullptr */)
{
if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return;
@@ -836,7 +864,7 @@ hb_ot_layout_feature_with_variations_get_lookups (hb_face_t *face,
unsigned int *lookup_count /* IN/OUT */,
unsigned int *lookup_indexes /* OUT */)
{
- ASSERT_STATIC (OT::FeatureVariations::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_VARIATIONS_INDEX);
+ static_assert ((OT::FeatureVariations::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_VARIATIONS_INDEX), "");
const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
const OT::Feature &f = g.get_feature_variation (feature_index, variations_index);
@@ -944,11 +972,11 @@ hb_ot_layout_position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer)
**/
hb_bool_t
hb_ot_layout_get_size_params (hb_face_t *face,
- unsigned int *design_size, /* OUT. May be NULL */
- unsigned int *subfamily_id, /* OUT. May be NULL */
- unsigned int *subfamily_name_id, /* OUT. May be NULL */
- unsigned int *range_start, /* OUT. May be NULL */
- unsigned int *range_end /* OUT. May be NULL */)
+ unsigned int *design_size, /* OUT. May be nullptr */
+ unsigned int *subfamily_id, /* OUT. May be nullptr */
+ unsigned int *subfamily_name_id, /* OUT. May be nullptr */
+ unsigned int *range_start, /* OUT. May be nullptr */
+ unsigned int *range_end /* OUT. May be nullptr */)
{
const OT::GPOS &gpos = _get_gpos (face);
const hb_tag_t tag = HB_TAG ('s','i','z','e');
@@ -1196,6 +1224,7 @@ inline void hb_ot_map_t::apply (const Proxy &proxy,
c.set_lookup_index (lookup_index);
c.set_lookup_mask (lookups[table_index][i].mask);
c.set_auto_zwj (lookups[table_index][i].auto_zwj);
+ c.set_auto_zwnj (lookups[table_index][i].auto_zwnj);
apply_string<Proxy> (&c,
proxy.table.get_lookup (lookup_index),
proxy.accels[lookup_index]);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-map-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-map-private.hh
index 0395c9c22f..97b92cc9a8 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-map-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-map-private.hh
@@ -50,19 +50,25 @@ struct hb_ot_map_t
hb_mask_t mask;
hb_mask_t _1_mask; /* mask for value=1, for quick access */
unsigned int needs_fallback : 1;
+ unsigned int auto_zwnj : 1;
unsigned int auto_zwj : 1;
- static int cmp (const feature_map_t *a, const feature_map_t *b)
- { return a->tag < b->tag ? -1 : a->tag > b->tag ? 1 : 0; }
+ inline int cmp (const hb_tag_t *tag_) const
+ { return *tag_ < tag ? -1 : *tag_ > tag ? 1 : 0; }
};
struct lookup_map_t {
unsigned short index;
+ unsigned short auto_zwnj : 1;
unsigned short auto_zwj : 1;
hb_mask_t mask;
- static int cmp (const lookup_map_t *a, const lookup_map_t *b)
- { return a->index < b->index ? -1 : a->index > b->index ? 1 : 0; }
+ static int cmp (const void *pa, const void *pb)
+ {
+ const lookup_map_t *a = (const lookup_map_t *) pa;
+ const lookup_map_t *b = (const lookup_map_t *) pb;
+ return a->index < b->index ? -1 : a->index > b->index ? 1 : 0;
+ }
};
typedef void (*pause_func_t) (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer);
@@ -77,7 +83,7 @@ struct hb_ot_map_t
inline hb_mask_t get_global_mask (void) const { return global_mask; }
- inline hb_mask_t get_mask (hb_tag_t feature_tag, unsigned int *shift = NULL) const {
+ inline hb_mask_t get_mask (hb_tag_t feature_tag, unsigned int *shift = nullptr) const {
const feature_map_t *map = features.bsearch (&feature_tag);
if (shift) *shift = map ? map->shift : 0;
return map ? map->mask : 0;
@@ -106,14 +112,14 @@ struct hb_ot_map_t
inline void get_stage_lookups (unsigned int table_index, unsigned int stage,
const struct lookup_map_t **plookups, unsigned int *lookup_count) const {
if (unlikely (stage == (unsigned int) -1)) {
- *plookups = NULL;
+ *plookups = nullptr;
*lookup_count = 0;
return;
}
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];
+ *plookups = end == start ? nullptr : &lookups[table_index][start];
*lookup_count = end - start;
}
@@ -150,8 +156,9 @@ enum hb_ot_map_feature_flags_t {
F_NONE = 0x0000u,
F_GLOBAL = 0x0001u, /* Feature applies to all characters; results in no mask allocated for it. */
F_HAS_FALLBACK = 0x0002u, /* Has fallback implementation, so include mask bit even if feature not found. */
- F_MANUAL_ZWJ = 0x0004u, /* Don't skip over ZWJ when matching. */
- F_GLOBAL_SEARCH = 0x0008u /* If feature not found in LangSys, look for it in global feature list and pick one. */
+ F_MANUAL_ZWNJ = 0x0004u, /* Don't skip over ZWNJ when matching **context**. */
+ F_MANUAL_ZWJ = 0x0008u, /* Don't skip over ZWJ when matching **input**. */
+ F_GLOBAL_SEARCH = 0x0010u /* If feature not found in LangSys, look for it in global feature list and pick one. */
};
HB_MARK_AS_FLAG_T (hb_ot_map_feature_flags_t);
/* Macro version for where const is desired. */
@@ -196,7 +203,8 @@ struct hb_ot_map_builder_t
unsigned int feature_index,
unsigned int variations_index,
hb_mask_t mask,
- bool auto_zwj);
+ bool auto_zwnj = true,
+ bool auto_zwj = true);
struct feature_info_t {
hb_tag_t tag;
@@ -206,9 +214,13 @@ struct hb_ot_map_builder_t
unsigned int default_value; /* for non-global features, what should the unset glyphs take */
unsigned int stage[2]; /* GSUB/GPOS */
- static int cmp (const feature_info_t *a, const feature_info_t *b)
- { return (a->tag != b->tag) ? (a->tag < b->tag ? -1 : 1) :
- (a->seq < b->seq ? -1 : a->seq > b->seq ? 1 : 0); }
+ static int cmp (const void *pa, const void *pb)
+ {
+ const feature_info_t *a = (const feature_info_t *) pa;
+ const feature_info_t *b = (const feature_info_t *) pb;
+ return (a->tag != b->tag) ? (a->tag < b->tag ? -1 : 1) :
+ (a->seq < b->seq ? -1 : a->seq > b->seq ? 1 : 0);
+ }
};
struct stage_info_t {
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc
index 9b331d5210..ea9bde9a66 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc
@@ -85,6 +85,7 @@ hb_ot_map_builder_t::add_lookups (hb_ot_map_t &m,
unsigned int feature_index,
unsigned int variations_index,
hb_mask_t mask,
+ bool auto_zwnj,
bool auto_zwj)
{
unsigned int lookup_indices[32];
@@ -112,6 +113,7 @@ hb_ot_map_builder_t::add_lookups (hb_ot_map_t &m,
return;
lookup->mask = mask;
lookup->index = lookup_indices[i];
+ lookup->auto_zwnj = auto_zwnj;
lookup->auto_zwj = auto_zwj;
}
@@ -136,7 +138,11 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
const int *coords,
unsigned int num_coords)
{
- m.global_mask = 1;
+ static_assert ((!(HB_GLYPH_FLAG_DEFINED & (HB_GLYPH_FLAG_DEFINED + 1))), "");
+ unsigned int global_bit_mask = HB_GLYPH_FLAG_DEFINED + 1;
+ unsigned int global_bit_shift = _hb_popcount32 (HB_GLYPH_FLAG_DEFINED);
+
+ m.global_mask = global_bit_mask;
unsigned int required_feature_index[2];
hb_tag_t required_feature_tag[2];
@@ -188,7 +194,8 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
/* Allocate bits now */
- unsigned int next_bit = 1;
+ unsigned int next_bit = global_bit_shift + 1;
+
for (unsigned int i = 0; i < feature_infos.len; i++)
{
const feature_info_t *info = &feature_infos[i];
@@ -243,11 +250,12 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
map->index[1] = feature_index[1];
map->stage[0] = info->stage[0];
map->stage[1] = info->stage[1];
+ map->auto_zwnj = !(info->flags & F_MANUAL_ZWNJ);
map->auto_zwj = !(info->flags & F_MANUAL_ZWJ);
if ((info->flags & F_GLOBAL) && info->max_value == 1) {
/* Uses the global bit */
- map->shift = 0;
- map->mask = 1;
+ map->shift = global_bit_shift;
+ map->mask = global_bit_mask;
} else {
map->shift = next_bit;
map->mask = (1u << (next_bit + bits_needed)) - (1u << next_bit);
@@ -261,8 +269,8 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
feature_infos.shrink (0); /* Done with these */
- add_gsub_pause (NULL);
- add_gpos_pause (NULL);
+ add_gsub_pause (nullptr);
+ add_gpos_pause (nullptr);
for (unsigned int table_index = 0; table_index < 2; table_index++)
{
@@ -284,8 +292,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
add_lookups (m, face, table_index,
required_feature_index[table_index],
variations_index,
- 1 /* mask */,
- true /* auto_zwj */);
+ global_bit_mask);
for (unsigned i = 0; i < m.features.len; i++)
if (m.features[i].stage[table_index] == stage)
@@ -293,6 +300,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
m.features[i].index[table_index],
variations_index,
m.features[i].mask,
+ m.features[i].auto_zwnj,
m.features[i].auto_zwj);
/* Sort lookups and merge duplicates */
@@ -307,6 +315,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
else
{
m.lookups[table_index][j].mask |= m.lookups[table_index][i].mask;
+ m.lookups[table_index][j].auto_zwnj &= m.lookups[table_index][i].auto_zwnj;
m.lookups[table_index][j].auto_zwj &= m.lookups[table_index][i].auto_zwj;
}
m.lookups[table_index].shrink (j + 1);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-math-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-math-table.hh
new file mode 100644
index 0000000000..7dc3283a28
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-math-table.hh
@@ -0,0 +1,722 @@
+/*
+ * Copyright © 2016 Igalia S.L.
+ *
+ * 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.
+ *
+ * Igalia Author(s): Frédéric Wang
+ */
+
+#ifndef HB_OT_MATH_TABLE_HH
+#define HB_OT_MATH_TABLE_HH
+
+#include "hb-open-type-private.hh"
+#include "hb-ot-layout-common-private.hh"
+#include "hb-ot-math.h"
+
+namespace OT {
+
+
+struct MathValueRecord
+{
+ inline hb_position_t get_x_value (hb_font_t *font, const void *base) const
+ { return font->em_scale_x (value) + (base+deviceTable).get_x_delta (font); }
+ inline hb_position_t get_y_value (hb_font_t *font, const void *base) const
+ { return font->em_scale_y (value) + (base+deviceTable).get_y_delta (font); }
+
+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) && deviceTable.sanitize (c, base));
+ }
+
+ protected:
+ INT16 value; /* The X or Y value in design units */
+ OffsetTo<Device> deviceTable; /* Offset to the device table - from the
+ * beginning of parent table. May be nullptr.
+ * Suggested format for device table is 1. */
+
+ public:
+ DEFINE_SIZE_STATIC (4);
+};
+
+struct MathConstants
+{
+ inline bool sanitize_math_value_records (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+
+ unsigned int count = ARRAY_LENGTH (mathValueRecords);
+ for (unsigned int i = 0; i < count; i++)
+ if (!mathValueRecords[i].sanitize (c, this))
+ return_trace (false);
+
+ return_trace (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) && sanitize_math_value_records(c));
+ }
+
+ inline hb_position_t get_value (hb_ot_math_constant_t constant,
+ hb_font_t *font) const
+ {
+ switch (constant) {
+
+ case HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN:
+ case HB_OT_MATH_CONSTANT_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN:
+ return percentScaleDown[constant - HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN];
+
+ case HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT:
+ case HB_OT_MATH_CONSTANT_DISPLAY_OPERATOR_MIN_HEIGHT:
+ return font->em_scale_y (minHeight[constant - HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT]);
+
+ case HB_OT_MATH_CONSTANT_RADICAL_KERN_AFTER_DEGREE:
+ case HB_OT_MATH_CONSTANT_RADICAL_KERN_BEFORE_DEGREE:
+ case HB_OT_MATH_CONSTANT_SKEWED_FRACTION_HORIZONTAL_GAP:
+ case HB_OT_MATH_CONSTANT_SPACE_AFTER_SCRIPT:
+ return mathValueRecords[constant - HB_OT_MATH_CONSTANT_MATH_LEADING].get_x_value(font, this);
+
+ case HB_OT_MATH_CONSTANT_ACCENT_BASE_HEIGHT:
+ case HB_OT_MATH_CONSTANT_AXIS_HEIGHT:
+ case HB_OT_MATH_CONSTANT_FLATTENED_ACCENT_BASE_HEIGHT:
+ case HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_DISPLAY_STYLE_SHIFT_DOWN:
+ case HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_GAP_MIN:
+ case HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_SHIFT_DOWN:
+ case HB_OT_MATH_CONSTANT_FRACTION_DENOM_DISPLAY_STYLE_GAP_MIN:
+ case HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_DISPLAY_STYLE_SHIFT_UP:
+ case HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_GAP_MIN:
+ case HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_SHIFT_UP:
+ case HB_OT_MATH_CONSTANT_FRACTION_NUM_DISPLAY_STYLE_GAP_MIN:
+ case HB_OT_MATH_CONSTANT_FRACTION_RULE_THICKNESS:
+ case HB_OT_MATH_CONSTANT_LOWER_LIMIT_BASELINE_DROP_MIN:
+ case HB_OT_MATH_CONSTANT_LOWER_LIMIT_GAP_MIN:
+ case HB_OT_MATH_CONSTANT_MATH_LEADING:
+ case HB_OT_MATH_CONSTANT_OVERBAR_EXTRA_ASCENDER:
+ case HB_OT_MATH_CONSTANT_OVERBAR_RULE_THICKNESS:
+ case HB_OT_MATH_CONSTANT_OVERBAR_VERTICAL_GAP:
+ case HB_OT_MATH_CONSTANT_RADICAL_DISPLAY_STYLE_VERTICAL_GAP:
+ case HB_OT_MATH_CONSTANT_RADICAL_EXTRA_ASCENDER:
+ case HB_OT_MATH_CONSTANT_RADICAL_RULE_THICKNESS:
+ case HB_OT_MATH_CONSTANT_RADICAL_VERTICAL_GAP:
+ case HB_OT_MATH_CONSTANT_SKEWED_FRACTION_VERTICAL_GAP:
+ case HB_OT_MATH_CONSTANT_STACK_BOTTOM_DISPLAY_STYLE_SHIFT_DOWN:
+ case HB_OT_MATH_CONSTANT_STACK_BOTTOM_SHIFT_DOWN:
+ case HB_OT_MATH_CONSTANT_STACK_DISPLAY_STYLE_GAP_MIN:
+ case HB_OT_MATH_CONSTANT_STACK_GAP_MIN:
+ case HB_OT_MATH_CONSTANT_STACK_TOP_DISPLAY_STYLE_SHIFT_UP:
+ case HB_OT_MATH_CONSTANT_STACK_TOP_SHIFT_UP:
+ case HB_OT_MATH_CONSTANT_STRETCH_STACK_BOTTOM_SHIFT_DOWN:
+ case HB_OT_MATH_CONSTANT_STRETCH_STACK_GAP_ABOVE_MIN:
+ case HB_OT_MATH_CONSTANT_STRETCH_STACK_GAP_BELOW_MIN:
+ case HB_OT_MATH_CONSTANT_STRETCH_STACK_TOP_SHIFT_UP:
+ case HB_OT_MATH_CONSTANT_SUBSCRIPT_BASELINE_DROP_MIN:
+ case HB_OT_MATH_CONSTANT_SUBSCRIPT_SHIFT_DOWN:
+ case HB_OT_MATH_CONSTANT_SUBSCRIPT_TOP_MAX:
+ case HB_OT_MATH_CONSTANT_SUB_SUPERSCRIPT_GAP_MIN:
+ case HB_OT_MATH_CONSTANT_SUPERSCRIPT_BASELINE_DROP_MAX:
+ case HB_OT_MATH_CONSTANT_SUPERSCRIPT_BOTTOM_MAX_WITH_SUBSCRIPT:
+ case HB_OT_MATH_CONSTANT_SUPERSCRIPT_BOTTOM_MIN:
+ case HB_OT_MATH_CONSTANT_SUPERSCRIPT_SHIFT_UP:
+ case HB_OT_MATH_CONSTANT_SUPERSCRIPT_SHIFT_UP_CRAMPED:
+ case HB_OT_MATH_CONSTANT_UNDERBAR_EXTRA_DESCENDER:
+ case HB_OT_MATH_CONSTANT_UNDERBAR_RULE_THICKNESS:
+ case HB_OT_MATH_CONSTANT_UNDERBAR_VERTICAL_GAP:
+ case HB_OT_MATH_CONSTANT_UPPER_LIMIT_BASELINE_RISE_MIN:
+ case HB_OT_MATH_CONSTANT_UPPER_LIMIT_GAP_MIN:
+ return mathValueRecords[constant - HB_OT_MATH_CONSTANT_MATH_LEADING].get_y_value(font, this);
+
+ case HB_OT_MATH_CONSTANT_RADICAL_DEGREE_BOTTOM_RAISE_PERCENT:
+ return radicalDegreeBottomRaisePercent;
+
+ default:
+ return 0;
+ }
+ }
+
+ protected:
+ INT16 percentScaleDown[2];
+ UINT16 minHeight[2];
+ MathValueRecord mathValueRecords[51];
+ INT16 radicalDegreeBottomRaisePercent;
+
+ public:
+ DEFINE_SIZE_STATIC (214);
+};
+
+struct MathItalicsCorrectionInfo
+{
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ coverage.sanitize (c, this) &&
+ italicsCorrection.sanitize (c, this));
+ }
+
+ inline hb_position_t get_value (hb_codepoint_t glyph,
+ hb_font_t *font) const
+ {
+ unsigned int index = (this+coverage).get_coverage (glyph);
+ return italicsCorrection[index].get_x_value (font, this);
+ }
+
+ protected:
+ OffsetTo<Coverage> coverage; /* Offset to Coverage table -
+ * from the beginning of
+ * MathItalicsCorrectionInfo
+ * table. */
+ ArrayOf<MathValueRecord> italicsCorrection; /* Array of MathValueRecords
+ * defining italics correction
+ * values for each
+ * covered glyph. */
+
+ public:
+ DEFINE_SIZE_ARRAY (4, italicsCorrection);
+};
+
+struct MathTopAccentAttachment
+{
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ topAccentCoverage.sanitize (c, this) &&
+ topAccentAttachment.sanitize (c, this));
+ }
+
+ inline hb_position_t get_value (hb_codepoint_t glyph,
+ hb_font_t *font) const
+ {
+ unsigned int index = (this+topAccentCoverage).get_coverage (glyph);
+ if (index == NOT_COVERED)
+ return font->get_glyph_h_advance (glyph) / 2;
+ return topAccentAttachment[index].get_x_value(font, this);
+ }
+
+ protected:
+ OffsetTo<Coverage> topAccentCoverage; /* Offset to Coverage table -
+ * from the beginning of
+ * MathTopAccentAttachment
+ * table. */
+ ArrayOf<MathValueRecord> topAccentAttachment; /* Array of MathValueRecords
+ * defining top accent
+ * attachment points for each
+ * covered glyph. */
+
+ public:
+ DEFINE_SIZE_ARRAY (2 + 2, topAccentAttachment);
+};
+
+struct MathKern
+{
+ inline bool sanitize_math_value_records (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ unsigned int count = 2 * heightCount + 1;
+ for (unsigned int i = 0; i < count; i++)
+ if (!mathValueRecords[i].sanitize (c, this)) return_trace (false);
+ return_trace (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ c->check_array (mathValueRecords,
+ mathValueRecords[0].static_size,
+ 2 * heightCount + 1) &&
+ sanitize_math_value_records (c));
+ }
+
+ inline hb_position_t get_value (hb_position_t correction_height, hb_font_t *font) const
+ {
+ const MathValueRecord* correctionHeight = mathValueRecords;
+ const MathValueRecord* kernValue = mathValueRecords + heightCount;
+ int sign = font->y_scale < 0 ? -1 : +1;
+
+ /* The description of the MathKern table is a ambiguous, but interpreting
+ * "between the two heights found at those indexes" for 0 < i < len as
+ *
+ * correctionHeight[i-1] < correction_height <= correctionHeight[i]
+ *
+ * makes the result consistent with the limit cases and we can just use the
+ * binary search algorithm of std::upper_bound:
+ */
+ unsigned int i = 0;
+ unsigned int count = heightCount;
+ while (count > 0)
+ {
+ unsigned int half = count / 2;
+ hb_position_t height = correctionHeight[i + half].get_y_value(font, this);
+ if (sign * height < sign * correction_height)
+ {
+ i += half + 1;
+ count -= half + 1;
+ } else
+ count = half;
+ }
+ return kernValue[i].get_x_value(font, this);
+ }
+
+ protected:
+ UINT16 heightCount;
+ MathValueRecord mathValueRecords[VAR]; /* Array of correction heights at
+ * which the kern value changes.
+ * Sorted by the height value in
+ * design units (heightCount entries),
+ * Followed by:
+ * Array of kern values corresponding
+ * to heights. (heightCount+1 entries).
+ */
+
+ public:
+ DEFINE_SIZE_ARRAY (2, mathValueRecords);
+};
+
+struct MathKernInfoRecord
+{
+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+ {
+ TRACE_SANITIZE (this);
+
+ unsigned int count = ARRAY_LENGTH (mathKern);
+ for (unsigned int i = 0; i < count; i++)
+ if (unlikely (!mathKern[i].sanitize (c, base)))
+ return_trace (false);
+
+ return_trace (true);
+ }
+
+ inline hb_position_t get_kerning (hb_ot_math_kern_t kern,
+ hb_position_t correction_height,
+ hb_font_t *font,
+ const void *base) const
+ {
+ unsigned int idx = kern;
+ if (unlikely (idx >= ARRAY_LENGTH (mathKern))) return 0;
+ return (base+mathKern[idx]).get_value (correction_height, font);
+ }
+
+ protected:
+ /* Offset to MathKern table for each corner -
+ * from the beginning of MathKernInfo table. May be nullptr. */
+ OffsetTo<MathKern> mathKern[4];
+
+ public:
+ DEFINE_SIZE_STATIC (8);
+};
+
+struct MathKernInfo
+{
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ mathKernCoverage.sanitize (c, this) &&
+ mathKernInfoRecords.sanitize (c, this));
+ }
+
+ inline hb_position_t get_kerning (hb_codepoint_t glyph,
+ hb_ot_math_kern_t kern,
+ hb_position_t correction_height,
+ hb_font_t *font) const
+ {
+ unsigned int index = (this+mathKernCoverage).get_coverage (glyph);
+ return mathKernInfoRecords[index].get_kerning (kern, correction_height, font, this);
+ }
+
+ protected:
+ OffsetTo<Coverage> mathKernCoverage; /* Offset to Coverage table -
+ * from the beginning of the
+ * MathKernInfo table. */
+ ArrayOf<MathKernInfoRecord> mathKernInfoRecords; /* Array of
+ * MathKernInfoRecords,
+ * per-glyph information for
+ * mathematical positioning
+ * of subscripts and
+ * superscripts. */
+
+ public:
+ DEFINE_SIZE_ARRAY (4, mathKernInfoRecords);
+};
+
+struct MathGlyphInfo
+{
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ mathItalicsCorrectionInfo.sanitize (c, this) &&
+ mathTopAccentAttachment.sanitize (c, this) &&
+ extendedShapeCoverage.sanitize (c, this) &&
+ mathKernInfo.sanitize(c, this));
+ }
+
+ inline hb_position_t
+ get_italics_correction (hb_codepoint_t glyph, hb_font_t *font) const
+ { return (this+mathItalicsCorrectionInfo).get_value (glyph, font); }
+
+ inline hb_position_t
+ get_top_accent_attachment (hb_codepoint_t glyph, hb_font_t *font) const
+ { return (this+mathTopAccentAttachment).get_value (glyph, font); }
+
+ inline bool is_extended_shape (hb_codepoint_t glyph) const
+ { return (this+extendedShapeCoverage).get_coverage (glyph) != NOT_COVERED; }
+
+ inline hb_position_t get_kerning (hb_codepoint_t glyph,
+ hb_ot_math_kern_t kern,
+ hb_position_t correction_height,
+ hb_font_t *font) const
+ { return (this+mathKernInfo).get_kerning (glyph, kern, correction_height, font); }
+
+ protected:
+ /* Offset to MathItalicsCorrectionInfo table -
+ * from the beginning of MathGlyphInfo table. */
+ OffsetTo<MathItalicsCorrectionInfo> mathItalicsCorrectionInfo;
+
+ /* Offset to MathTopAccentAttachment table -
+ * from the beginning of MathGlyphInfo table. */
+ OffsetTo<MathTopAccentAttachment> mathTopAccentAttachment;
+
+ /* Offset to coverage table for Extended Shape glyphs -
+ * from the beginning of MathGlyphInfo table. When the left or right glyph of
+ * a box is an extended shape variant, the (ink) box (and not the default
+ * position defined by values in MathConstants table) should be used for
+ * vertical positioning purposes. May be nullptr.. */
+ OffsetTo<Coverage> extendedShapeCoverage;
+
+ /* Offset to MathKernInfo table -
+ * from the beginning of MathGlyphInfo table. */
+ OffsetTo<MathKernInfo> mathKernInfo;
+
+ public:
+ DEFINE_SIZE_STATIC (8);
+};
+
+struct MathGlyphVariantRecord
+{
+ friend struct MathGlyphConstruction;
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this));
+ }
+
+ protected:
+ GlyphID variantGlyph; /* Glyph ID for the variant. */
+ UINT16 advanceMeasurement; /* Advance width/height, in design units, of the
+ * variant, in the direction of requested
+ * glyph extension. */
+
+ public:
+ DEFINE_SIZE_STATIC (4);
+};
+
+struct PartFlags : UINT16
+{
+ enum Flags {
+ Extender = 0x0001u, /* If set, the part can be skipped or repeated. */
+
+ Defined = 0x0001u, /* All defined flags. */
+ };
+
+ public:
+ DEFINE_SIZE_STATIC (2);
+};
+
+struct MathGlyphPartRecord
+{
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this));
+ }
+
+ inline void extract (hb_ot_math_glyph_part_t &out,
+ int scale,
+ hb_font_t *font) const
+ {
+ out.glyph = glyph;
+
+ out.start_connector_length = font->em_scale (startConnectorLength, scale);
+ out.end_connector_length = font->em_scale (endConnectorLength, scale);
+ out.full_advance = font->em_scale (fullAdvance, scale);
+
+ static_assert ((unsigned int) HB_MATH_GLYPH_PART_FLAG_EXTENDER ==
+ (unsigned int) PartFlags::Extender, "");
+
+ out.flags = (hb_ot_math_glyph_part_flags_t)
+ (unsigned int)
+ (partFlags & PartFlags::Defined);
+ }
+
+ protected:
+ GlyphID glyph; /* Glyph ID for the part. */
+ UINT16 startConnectorLength; /* Advance width/ height of the straight bar
+ * connector material, in design units, is at
+ * the beginning of the glyph, in the
+ * direction of the extension. */
+ UINT16 endConnectorLength; /* Advance width/ height of the straight bar
+ * connector material, in design units, is at
+ * the end of the glyph, in the direction of
+ * the extension. */
+ UINT16 fullAdvance; /* Full advance width/height for this part,
+ * in the direction of the extension.
+ * In design units. */
+ PartFlags partFlags; /* Part qualifiers. */
+
+ public:
+ DEFINE_SIZE_STATIC (10);
+};
+
+struct MathGlyphAssembly
+{
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ italicsCorrection.sanitize(c, this) &&
+ partRecords.sanitize(c));
+ }
+
+ inline unsigned int get_parts (hb_direction_t direction,
+ hb_font_t *font,
+ unsigned int start_offset,
+ unsigned int *parts_count, /* IN/OUT */
+ hb_ot_math_glyph_part_t *parts /* OUT */,
+ hb_position_t *italics_correction /* OUT */) const
+ {
+ if (parts_count)
+ {
+ int scale = font->dir_scale (direction);
+ const MathGlyphPartRecord *arr =
+ partRecords.sub_array (start_offset, parts_count);
+ unsigned int count = *parts_count;
+ for (unsigned int i = 0; i < count; i++)
+ arr[i].extract (parts[i], scale, font);
+ }
+
+ if (italics_correction)
+ *italics_correction = italicsCorrection.get_x_value (font, this);
+
+ return partRecords.len;
+ }
+
+ protected:
+ MathValueRecord italicsCorrection; /* Italics correction of this
+ * MathGlyphAssembly. Should not
+ * depend on the assembly size. */
+ ArrayOf<MathGlyphPartRecord> partRecords; /* Array of part records, from
+ * left to right and bottom to
+ * top. */
+
+ public:
+ DEFINE_SIZE_ARRAY (6, partRecords);
+};
+
+struct MathGlyphConstruction
+{
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ glyphAssembly.sanitize(c, this) &&
+ mathGlyphVariantRecord.sanitize(c));
+ }
+
+ inline const MathGlyphAssembly &get_assembly (void) const
+ { return this+glyphAssembly; }
+
+ inline unsigned int get_variants (hb_direction_t direction,
+ hb_font_t *font,
+ unsigned int start_offset,
+ unsigned int *variants_count, /* IN/OUT */
+ hb_ot_math_glyph_variant_t *variants /* OUT */) const
+ {
+ if (variants_count)
+ {
+ int scale = font->dir_scale (direction);
+ const MathGlyphVariantRecord *arr =
+ mathGlyphVariantRecord.sub_array (start_offset, variants_count);
+ unsigned int count = *variants_count;
+ for (unsigned int i = 0; i < count; i++)
+ {
+ variants[i].glyph = arr[i].variantGlyph;
+ variants[i].advance = font->em_scale (arr[i].advanceMeasurement, scale);
+ }
+ }
+ return mathGlyphVariantRecord.len;
+ }
+
+ protected:
+ /* Offset to MathGlyphAssembly table for this shape - from the beginning of
+ MathGlyphConstruction table. May be nullptr. */
+ OffsetTo<MathGlyphAssembly> glyphAssembly;
+
+ /* MathGlyphVariantRecords for alternative variants of the glyphs. */
+ ArrayOf<MathGlyphVariantRecord> mathGlyphVariantRecord;
+
+ public:
+ DEFINE_SIZE_ARRAY (4, mathGlyphVariantRecord);
+};
+
+struct MathVariants
+{
+ inline bool sanitize_offsets (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ unsigned int count = vertGlyphCount + horizGlyphCount;
+ for (unsigned int i = 0; i < count; i++)
+ if (!glyphConstruction[i].sanitize (c, this)) return_trace (false);
+ return_trace (true);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ vertGlyphCoverage.sanitize (c, this) &&
+ horizGlyphCoverage.sanitize (c, this) &&
+ c->check_array (glyphConstruction,
+ glyphConstruction[0].static_size,
+ vertGlyphCount + horizGlyphCount) &&
+ sanitize_offsets (c));
+ }
+
+ inline hb_position_t get_min_connector_overlap (hb_direction_t direction,
+ hb_font_t *font) const
+ { return font->em_scale_dir (minConnectorOverlap, direction); }
+
+ inline unsigned int get_glyph_variants (hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_font_t *font,
+ unsigned int start_offset,
+ unsigned int *variants_count, /* IN/OUT */
+ hb_ot_math_glyph_variant_t *variants /* OUT */) const
+ { return get_glyph_construction (glyph, direction, font)
+ .get_variants (direction, font, start_offset, variants_count, variants); }
+
+ inline unsigned int get_glyph_parts (hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_font_t *font,
+ unsigned int start_offset,
+ unsigned int *parts_count, /* IN/OUT */
+ hb_ot_math_glyph_part_t *parts /* OUT */,
+ hb_position_t *italics_correction /* OUT */) const
+ { return get_glyph_construction (glyph, direction, font)
+ .get_assembly ()
+ .get_parts (direction, font,
+ start_offset, parts_count, parts,
+ italics_correction); }
+
+ private:
+ inline const MathGlyphConstruction &
+ get_glyph_construction (hb_codepoint_t glyph,
+ hb_direction_t direction,
+ hb_font_t *font) const
+ {
+ bool vertical = HB_DIRECTION_IS_VERTICAL (direction);
+ unsigned int count = vertical ? vertGlyphCount : horizGlyphCount;
+ const OffsetTo<Coverage> &coverage = vertical ? vertGlyphCoverage
+ : horizGlyphCoverage;
+
+ unsigned int index = (this+coverage).get_coverage (glyph);
+ if (unlikely (index >= count)) return Null(MathGlyphConstruction);
+
+ if (!vertical)
+ index += vertGlyphCount;
+
+ return this+glyphConstruction[index];
+ }
+
+ protected:
+ UINT16 minConnectorOverlap; /* Minimum overlap of connecting
+ * glyphs during glyph construction,
+ * in design units. */
+ OffsetTo<Coverage> vertGlyphCoverage; /* Offset to Coverage table -
+ * from the beginning of MathVariants
+ * table. */
+ OffsetTo<Coverage> horizGlyphCoverage; /* Offset to Coverage table -
+ * from the beginning of MathVariants
+ * table. */
+ UINT16 vertGlyphCount; /* Number of glyphs for which
+ * information is provided for
+ * vertically growing variants. */
+ UINT16 horizGlyphCount; /* Number of glyphs for which
+ * information is provided for
+ * horizontally growing variants. */
+
+ /* Array of offsets to MathGlyphConstruction tables - from the beginning of
+ the MathVariants table, for shapes growing in vertical/horizontal
+ direction. */
+ OffsetTo<MathGlyphConstruction> glyphConstruction[VAR];
+
+ public:
+ DEFINE_SIZE_ARRAY (10, glyphConstruction);
+};
+
+
+/*
+ * MATH -- The MATH Table
+ */
+
+struct MATH
+{
+ static const hb_tag_t tableTag = HB_OT_TAG_MATH;
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (version.sanitize (c) &&
+ likely (version.major == 1) &&
+ mathConstants.sanitize (c, this) &&
+ mathGlyphInfo.sanitize (c, this) &&
+ mathVariants.sanitize (c, this));
+ }
+
+ inline hb_position_t get_constant (hb_ot_math_constant_t constant,
+ hb_font_t *font) const
+ { return (this+mathConstants).get_value (constant, font); }
+
+ inline const MathGlyphInfo &get_math_glyph_info (void) const
+ { return this+mathGlyphInfo; }
+
+ inline const MathVariants &get_math_variants (void) const
+ { return this+mathVariants; }
+
+ protected:
+ FixedVersion<>version; /* Version of the MATH table
+ * initially set to 0x00010000u */
+ OffsetTo<MathConstants> mathConstants;/* MathConstants table */
+ OffsetTo<MathGlyphInfo> mathGlyphInfo;/* MathGlyphInfo table */
+ OffsetTo<MathVariants> mathVariants; /* MathVariants table */
+
+ public:
+ DEFINE_SIZE_STATIC (10);
+};
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_MATH_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-math.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-math.cc
index 9ef21d2995..f82a07353c 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-math.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-math.cc
@@ -26,33 +26,15 @@
#include "hb-open-type-private.hh"
-#include "hb-ot-layout-math-table.hh"
-
-HB_SHAPER_DATA_ENSURE_DECLARE(ot, face)
+#include "hb-ot-layout-private.hh"
+#include "hb-ot-math-table.hh"
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);
-
-retry:
- const OT::MATH *math = (const OT::MATH *) hb_atomic_ptr_get (&layout->math);
-
- if (unlikely (!math))
- {
- hb_blob_t *blob = OT::Sanitizer<OT::MATH>::sanitize (face->reference_table (HB_OT_TAG_MATH));
- math = OT::Sanitizer<OT::MATH>::lock_instance (blob);
- if (!hb_atomic_ptr_cmpexch (&layout->math, NULL, math))
- {
- hb_blob_destroy (blob);
- goto retry;
- }
- layout->math_blob = blob;
- }
-
- return *math;
+ return *(layout->math.get ());
}
/*
@@ -64,10 +46,9 @@ retry:
* @face: #hb_face_t to test
*
* This function allows to verify the presence of an OpenType MATH table on the
- * face. If so, such a table will be loaded into memory and sanitized. You can
- * then safely call other functions for math layout and shaping.
+ * face.
*
- * Return value: #TRUE if face has a MATH table and #FALSE otherwise
+ * Return value: true if face has a MATH table, false otherwise
*
* Since: 1.3.3
**/
@@ -136,10 +117,10 @@ hb_ot_math_get_glyph_top_accent_attachment (hb_font_t *font,
/**
* hb_ot_math_is_glyph_extended_shape:
- * @font: a #hb_font_t to test
+ * @face: a #hb_face_t to test
* @glyph: a glyph index to test
*
- * Return value: #TRUE if the glyph is an extended shape and #FALSE otherwise
+ * Return value: true if the glyph is an extended shape, false otherwise
*
* Since: 1.3.3
**/
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh
index 943e3908c7..f6d283eb14 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh
@@ -60,7 +60,7 @@ struct maxp
protected:
FixedVersion<>version; /* Version of the maxp table (0.5 or 1.0),
* 0x00005000u or 0x00010000u. */
- USHORT numGlyphs; /* The number of glyphs in the font. */
+ UINT16 numGlyphs; /* The number of glyphs in the font. */
public:
DEFINE_SIZE_STATIC (6);
};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh
index 870f123325..4c5b3c0f98 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh
@@ -42,8 +42,10 @@ namespace OT {
struct NameRecord
{
- static int cmp (const NameRecord *a, const NameRecord *b)
+ static int cmp (const void *pa, const void *pb)
{
+ const NameRecord *a = (const NameRecord *) pa;
+ const NameRecord *b = (const NameRecord *) pb;
int ret;
ret = b->platformID.cmp (a->platformID);
if (ret) return ret;
@@ -63,12 +65,12 @@ struct NameRecord
return_trace (c->check_struct (this) && c->check_range ((char *) base, (unsigned int) length + offset));
}
- USHORT platformID; /* Platform ID. */
- USHORT encodingID; /* Platform-specific encoding ID. */
- USHORT languageID; /* Language ID. */
- USHORT nameID; /* Name ID. */
- USHORT length; /* String length (in bytes). */
- USHORT offset; /* String offset from start of storage area (in bytes). */
+ UINT16 platformID; /* Platform ID. */
+ UINT16 encodingID; /* Platform-specific encoding ID. */
+ UINT16 languageID; /* Language ID. */
+ UINT16 nameID; /* Name ID. */
+ UINT16 length; /* String length (in bytes). */
+ UINT16 offset; /* String offset from start of storage area (in bytes). */
public:
DEFINE_SIZE_STATIC (12);
};
@@ -89,7 +91,7 @@ struct name
key.encodingID.set (encoding_id);
key.languageID.set (language_id);
key.nameID.set (name_id);
- NameRecord *match = (NameRecord *) bsearch (&key, nameRecord, count, sizeof (nameRecord[0]), (hb_compare_func_t) NameRecord::cmp);
+ NameRecord *match = (NameRecord *) bsearch (&key, nameRecord, count, sizeof (nameRecord[0]), NameRecord::cmp);
if (!match)
return 0;
@@ -121,9 +123,9 @@ struct name
}
/* We only implement format 0 for now. */
- USHORT format; /* Format selector (=0/1). */
- USHORT count; /* Number of name records. */
- Offset<> stringOffset; /* Offset to start of string storage (from start of table). */
+ UINT16 format; /* Format selector (=0/1). */
+ UINT16 count; /* Number of name records. */
+ Offset16 stringOffset; /* Offset to start of string storage (from start of table). */
NameRecord nameRecord[VAR]; /* The name records where count is the number of records. */
public:
DEFINE_SIZE_ARRAY (6, nameRecord);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-os2-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-os2-table.hh
index 4709cd6e87..aa78f1e0a6 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-os2-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-os2-table.hh
@@ -50,50 +50,50 @@ struct os2
}
public:
- USHORT version;
+ UINT16 version;
/* Version 0 */
- SHORT xAvgCharWidth;
- USHORT usWeightClass;
- USHORT usWidthClass;
- USHORT fsType;
- SHORT ySubscriptXSize;
- SHORT ySubscriptYSize;
- SHORT ySubscriptXOffset;
- SHORT ySubscriptYOffset;
- SHORT ySuperscriptXSize;
- SHORT ySuperscriptYSize;
- SHORT ySuperscriptXOffset;
- SHORT ySuperscriptYOffset;
- SHORT yStrikeoutSize;
- SHORT yStrikeoutPosition;
- SHORT sFamilyClass;
- BYTE panose[10];
- ULONG ulUnicodeRange[4];
+ INT16 xAvgCharWidth;
+ UINT16 usWeightClass;
+ UINT16 usWidthClass;
+ UINT16 fsType;
+ INT16 ySubscriptXSize;
+ INT16 ySubscriptYSize;
+ INT16 ySubscriptXOffset;
+ INT16 ySubscriptYOffset;
+ INT16 ySuperscriptXSize;
+ INT16 ySuperscriptYSize;
+ INT16 ySuperscriptXOffset;
+ INT16 ySuperscriptYOffset;
+ INT16 yStrikeoutSize;
+ INT16 yStrikeoutPosition;
+ INT16 sFamilyClass;
+ UINT8 panose[10];
+ UINT32 ulUnicodeRange[4];
Tag achVendID;
- USHORT fsSelection;
- USHORT usFirstCharIndex;
- USHORT usLastCharIndex;
- SHORT sTypoAscender;
- SHORT sTypoDescender;
- SHORT sTypoLineGap;
- USHORT usWinAscent;
- USHORT usWinDescent;
+ UINT16 fsSelection;
+ UINT16 usFirstCharIndex;
+ UINT16 usLastCharIndex;
+ INT16 sTypoAscender;
+ INT16 sTypoDescender;
+ INT16 sTypoLineGap;
+ UINT16 usWinAscent;
+ UINT16 usWinDescent;
/* Version 1 */
- //ULONG ulCodePageRange1;
- //ULONG ulCodePageRange2;
+ //UINT32 ulCodePageRange1;
+ //UINT32 ulCodePageRange2;
/* Version 2 */
- //SHORT sxHeight;
- //SHORT sCapHeight;
- //USHORT usDefaultChar;
- //USHORT usBreakChar;
- //USHORT usMaxContext;
+ //INT16 sxHeight;
+ //INT16 sCapHeight;
+ //UINT16 usDefaultChar;
+ //UINT16 usBreakChar;
+ //UINT16 usMaxContext;
/* Version 5 */
- //USHORT usLowerOpticalPointSize;
- //USHORT usUpperOpticalPointSize;
+ //UINT16 usLowerOpticalPointSize;
+ //UINT16 usUpperOpticalPointSize;
public:
DEFINE_SIZE_STATIC (78);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-post-macroman.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-post-macroman.hh
new file mode 100644
index 0000000000..dbbb97e5a9
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-post-macroman.hh
@@ -0,0 +1,294 @@
+/*
+ * 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_POST_MACROMAN_HH
+#if 0 /* Make checks happy. */
+#define HB_OT_POST_MACROMAN_HH
+#include "hb-private.hh"
+#endif
+
+
+_S(".notdef")
+_S(".null")
+_S("nonmarkingreturn")
+_S("space")
+_S("exclam")
+_S("quotedbl")
+_S("numbersign")
+_S("dollar")
+_S("percent")
+_S("ampersand")
+_S("quotesingle")
+_S("parenleft")
+_S("parenright")
+_S("asterisk")
+_S("plus")
+_S("comma")
+_S("hyphen")
+_S("period")
+_S("slash")
+_S("zero")
+_S("one")
+_S("two")
+_S("three")
+_S("four")
+_S("five")
+_S("six")
+_S("seven")
+_S("eight")
+_S("nine")
+_S("colon")
+_S("semicolon")
+_S("less")
+_S("equal")
+_S("greater")
+_S("question")
+_S("at")
+_S("A")
+_S("B")
+_S("C")
+_S("D")
+_S("E")
+_S("F")
+_S("G")
+_S("H")
+_S("I")
+_S("J")
+_S("K")
+_S("L")
+_S("M")
+_S("N")
+_S("O")
+_S("P")
+_S("Q")
+_S("R")
+_S("S")
+_S("T")
+_S("U")
+_S("V")
+_S("W")
+_S("X")
+_S("Y")
+_S("Z")
+_S("bracketleft")
+_S("backslash")
+_S("bracketright")
+_S("asciicircum")
+_S("underscore")
+_S("grave")
+_S("a")
+_S("b")
+_S("c")
+_S("d")
+_S("e")
+_S("f")
+_S("g")
+_S("h")
+_S("i")
+_S("j")
+_S("k")
+_S("l")
+_S("m")
+_S("n")
+_S("o")
+_S("p")
+_S("q")
+_S("r")
+_S("s")
+_S("t")
+_S("u")
+_S("v")
+_S("w")
+_S("x")
+_S("y")
+_S("z")
+_S("braceleft")
+_S("bar")
+_S("braceright")
+_S("asciitilde")
+_S("Adieresis")
+_S("Aring")
+_S("Ccedilla")
+_S("Eacute")
+_S("Ntilde")
+_S("Odieresis")
+_S("Udieresis")
+_S("aacute")
+_S("agrave")
+_S("acircumflex")
+_S("adieresis")
+_S("atilde")
+_S("aring")
+_S("ccedilla")
+_S("eacute")
+_S("egrave")
+_S("ecircumflex")
+_S("edieresis")
+_S("iacute")
+_S("igrave")
+_S("icircumflex")
+_S("idieresis")
+_S("ntilde")
+_S("oacute")
+_S("ograve")
+_S("ocircumflex")
+_S("odieresis")
+_S("otilde")
+_S("uacute")
+_S("ugrave")
+_S("ucircumflex")
+_S("udieresis")
+_S("dagger")
+_S("degree")
+_S("cent")
+_S("sterling")
+_S("section")
+_S("bullet")
+_S("paragraph")
+_S("germandbls")
+_S("registered")
+_S("copyright")
+_S("trademark")
+_S("acute")
+_S("dieresis")
+_S("notequal")
+_S("AE")
+_S("Oslash")
+_S("infinity")
+_S("plusminus")
+_S("lessequal")
+_S("greaterequal")
+_S("yen")
+_S("mu")
+_S("partialdiff")
+_S("summation")
+_S("product")
+_S("pi")
+_S("integral")
+_S("ordfeminine")
+_S("ordmasculine")
+_S("Omega")
+_S("ae")
+_S("oslash")
+_S("questiondown")
+_S("exclamdown")
+_S("logicalnot")
+_S("radical")
+_S("florin")
+_S("approxequal")
+_S("Delta")
+_S("guillemotleft")
+_S("guillemotright")
+_S("ellipsis")
+_S("nonbreakingspace")
+_S("Agrave")
+_S("Atilde")
+_S("Otilde")
+_S("OE")
+_S("oe")
+_S("endash")
+_S("emdash")
+_S("quotedblleft")
+_S("quotedblright")
+_S("quoteleft")
+_S("quoteright")
+_S("divide")
+_S("lozenge")
+_S("ydieresis")
+_S("Ydieresis")
+_S("fraction")
+_S("currency")
+_S("guilsinglleft")
+_S("guilsinglright")
+_S("fi")
+_S("fl")
+_S("daggerdbl")
+_S("periodcentered")
+_S("quotesinglbase")
+_S("quotedblbase")
+_S("perthousand")
+_S("Acircumflex")
+_S("Ecircumflex")
+_S("Aacute")
+_S("Edieresis")
+_S("Egrave")
+_S("Iacute")
+_S("Icircumflex")
+_S("Idieresis")
+_S("Igrave")
+_S("Oacute")
+_S("Ocircumflex")
+_S("apple")
+_S("Ograve")
+_S("Uacute")
+_S("Ucircumflex")
+_S("Ugrave")
+_S("dotlessi")
+_S("circumflex")
+_S("tilde")
+_S("macron")
+_S("breve")
+_S("dotaccent")
+_S("ring")
+_S("cedilla")
+_S("hungarumlaut")
+_S("ogonek")
+_S("caron")
+_S("Lslash")
+_S("lslash")
+_S("Scaron")
+_S("scaron")
+_S("Zcaron")
+_S("zcaron")
+_S("brokenbar")
+_S("Eth")
+_S("eth")
+_S("Yacute")
+_S("yacute")
+_S("Thorn")
+_S("thorn")
+_S("minus")
+_S("multiply")
+_S("onesuperior")
+_S("twosuperior")
+_S("threesuperior")
+_S("onehalf")
+_S("onequarter")
+_S("threequarters")
+_S("franc")
+_S("Gbreve")
+_S("gbreve")
+_S("Idotaccent")
+_S("Scedilla")
+_S("scedilla")
+_S("Cacute")
+_S("cacute")
+_S("Ccaron")
+_S("ccaron")
+_S("dcroat")
+
+
+#endif /* HB_OT_POST_MACROMAN_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh
index 82ab3882a8..7f1c2c420f 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh
@@ -28,7 +28,15 @@
#define HB_OT_POST_TABLE_HH
#include "hb-open-type-private.hh"
+#include "hb-dsalgs.hh"
+#define HB_STRING_ARRAY_NAME format1_names
+#define HB_STRING_ARRAY_LIST "hb-ot-post-macroman.hh"
+#include "hb-string-array.hh"
+#undef HB_STRING_ARRAY_LIST
+#undef HB_STRING_ARRAY_NAME
+
+#define NUM_FORMAT1_NAMES 258
namespace OT {
@@ -45,16 +53,13 @@ struct postV2Tail
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
- return_trace (numberOfGlyphs.sanitize (c) &&
- c->check_array (glyphNameIndex, sizeof (USHORT), numberOfGlyphs));
+ return_trace (glyphNameIndex.sanitize (c));
}
- USHORT numberOfGlyphs; /* Number of glyphs (this should be the
- * same as numGlyphs in 'maxp' table). */
- USHORT glyphNameIndex[VAR]; /* This is not an offset, but is the
+ ArrayOf<UINT16>glyphNameIndex; /* This is not an offset, but is the
* ordinal number of the glyph in 'post'
* string tables. */
- BYTE namesX[VAR]; /* Glyph names with length bytes [variable]
+ UINT8 namesX[VAR]; /* Glyph names with length bytes [variable]
* (a Pascal string). */
DEFINE_SIZE_ARRAY2 (2, glyphNameIndex, namesX);
@@ -71,12 +76,170 @@ struct post
return_trace (false);
if (version.to_int () == 0x00020000)
{
- const postV2Tail &v2 = StructAfter<postV2Tail>(*this);
+ const postV2Tail &v2 = StructAfter<postV2Tail> (*this);
return_trace (v2.sanitize (c));
}
return_trace (true);
}
+ struct accelerator_t
+ {
+ inline void init (hb_face_t *face)
+ {
+ blob = Sanitizer<post>::sanitize (face->reference_table (HB_OT_TAG_post));
+ const post *table = Sanitizer<post>::lock_instance (blob);
+ unsigned int table_length = hb_blob_get_length (blob);
+
+ version = table->version.to_int ();
+ index_to_offset.init ();
+ if (version != 0x00020000)
+ return;
+
+ const postV2Tail &v2 = StructAfter<postV2Tail> (*table);
+
+ glyphNameIndex = &v2.glyphNameIndex;
+ pool = &StructAfter<uint8_t> (v2.glyphNameIndex);
+
+ const uint8_t *end = (uint8_t *) table + table_length;
+ for (const uint8_t *data = pool; data < end && data + *data <= end; data += 1 + *data)
+ {
+ uint32_t *offset = index_to_offset.push ();
+ if (unlikely (!offset))
+ break;
+ *offset = data - pool;
+ }
+ }
+ inline void fini (void)
+ {
+ index_to_offset.finish ();
+ free (gids_sorted_by_name);
+ }
+
+ inline bool get_glyph_name (hb_codepoint_t glyph,
+ char *buf, unsigned int buf_len) const
+ {
+ hb_string_t s = find_glyph_name (glyph);
+ if (!s.len)
+ return false;
+ if (!buf_len)
+ return true;
+ if (buf_len <= s.len) /* What to do with truncation? Returning false for now. */
+ return false;
+ strncpy (buf, s.bytes, s.len);
+ buf[s.len] = '\0';
+ return true;
+ }
+
+ inline bool get_glyph_from_name (const char *name, int len,
+ hb_codepoint_t *glyph) const
+ {
+ unsigned int count = get_glyph_count ();
+ if (unlikely (!count))
+ return false;
+
+ if (len < 0)
+ len = strlen (name);
+
+ if (unlikely (!len))
+ return false;
+
+ retry:
+ uint16_t *gids = (uint16_t *) hb_atomic_ptr_get (&gids_sorted_by_name);
+
+ if (unlikely (!gids))
+ {
+ gids = (uint16_t *) malloc (count * sizeof (gids[0]));
+ if (unlikely (!gids))
+ return false; /* Anything better?! */
+
+ for (unsigned int i = 0; i < count; i++)
+ gids[i] = i;
+ hb_sort_r (gids, count, sizeof (gids[0]), cmp_gids, (void *) this);
+
+ if (!hb_atomic_ptr_cmpexch (&gids_sorted_by_name, nullptr, gids)) {
+ free (gids);
+ goto retry;
+ }
+ }
+
+ hb_string_t st (name, len);
+ const uint16_t *gid = (const uint16_t *) hb_bsearch_r (&st, gids, count, sizeof (gids[0]), cmp_key, (void *) this);
+ if (gid)
+ {
+ *glyph = *gid;
+ return true;
+ }
+
+ return false;
+ }
+
+ protected:
+
+ inline unsigned int get_glyph_count (void) const
+ {
+ if (version == 0x00010000)
+ return NUM_FORMAT1_NAMES;
+
+ if (version == 0x00020000)
+ return glyphNameIndex->len;
+
+ return 0;
+ }
+
+ static inline int cmp_gids (const void *pa, const void *pb, void *arg)
+ {
+ const accelerator_t *thiz = (const accelerator_t *) arg;
+ uint16_t a = * (const uint16_t *) pa;
+ uint16_t b = * (const uint16_t *) pb;
+ return thiz->find_glyph_name (b).cmp (thiz->find_glyph_name (a));
+ }
+
+ static inline int cmp_key (const void *pk, const void *po, void *arg)
+ {
+ const accelerator_t *thiz = (const accelerator_t *) arg;
+ const hb_string_t *key = (const hb_string_t *) pk;
+ uint16_t o = * (const uint16_t *) po;
+ return thiz->find_glyph_name (o).cmp (*key);
+ }
+
+ inline hb_string_t find_glyph_name (hb_codepoint_t glyph) const
+ {
+ if (version == 0x00010000)
+ {
+ if (glyph >= NUM_FORMAT1_NAMES)
+ return hb_string_t ();
+
+ return format1_names (glyph);
+ }
+
+ if (version != 0x00020000 || glyph >= glyphNameIndex->len)
+ return hb_string_t ();
+
+ unsigned int index = glyphNameIndex->array[glyph];
+ if (index < NUM_FORMAT1_NAMES)
+ return format1_names (index);
+ index -= NUM_FORMAT1_NAMES;
+
+ if (index >= index_to_offset.len)
+ return hb_string_t ();
+ unsigned int offset = index_to_offset.array[index];
+
+ const uint8_t *data = pool + offset;
+ unsigned int name_length = *data;
+ data++;
+
+ return hb_string_t ((const char *) data, name_length);
+ }
+
+ private:
+ hb_blob_t *blob;
+ uint32_t version;
+ const ArrayOf<UINT16> *glyphNameIndex;
+ hb_prealloced_array_t<uint32_t, 1> index_to_offset;
+ const uint8_t *pool;
+ mutable uint16_t *gids_sorted_by_name;
+ };
+
public:
FixedVersion<>version; /* 0x00010000 for version 1.0
* 0x00020000 for version 2.0
@@ -98,16 +261,16 @@ struct post
* from the value of this field. */
FWORD underlineThickness; /* Suggested values for the underline
thickness. */
- ULONG isFixedPitch; /* Set to 0 if the font is proportionally
+ UINT32 isFixedPitch; /* Set to 0 if the font is proportionally
* spaced, non-zero if the font is not
* proportionally spaced (i.e. monospaced). */
- ULONG minMemType42; /* Minimum memory usage when an OpenType font
+ UINT32 minMemType42; /* Minimum memory usage when an OpenType font
* is downloaded. */
- ULONG maxMemType42; /* Maximum memory usage when an OpenType font
+ UINT32 maxMemType42; /* Maximum memory usage when an OpenType font
* is downloaded. */
- ULONG minMemType1; /* Minimum memory usage when an OpenType font
+ UINT32 minMemType1; /* Minimum memory usage when an OpenType font
* is downloaded as a Type 1 font. */
- ULONG maxMemType1; /* Maximum memory usage when an OpenType font
+ UINT32 maxMemType1; /* Maximum memory usage when an OpenType font
* is downloaded as a Type 1 font. */
/*postV2Tail v2[VAR];*/
DEFINE_SIZE_STATIC (32);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh
index d97d285210..d98cde121c 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh
@@ -73,11 +73,11 @@ arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUS
}
if (!num_glyphs)
- return NULL;
+ return nullptr;
/* Bubble-sort or something equally good!
* May not be good-enough for presidential candidate interviews, but good-enough for us... */
- hb_stable_sort (&glyphs[0], num_glyphs, OT::GlyphID::cmp, &substitutes[0]);
+ hb_stable_sort (&glyphs[0], num_glyphs, (int(*)(const OT::GlyphID*, const OT::GlyphID *)) OT::GlyphID::cmp, &substitutes[0]);
OT::Supplier<OT::GlyphID> glyphs_supplier (glyphs, num_glyphs);
OT::Supplier<OT::GlyphID> substitutes_supplier (substitutes, num_glyphs);
@@ -94,7 +94,7 @@ arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUS
c.end_serialize ();
/* TODO sanitize the results? */
- return ret ? c.copy<OT::SubstLookup> () : NULL;
+ return ret ? c.copy<OT::SubstLookup> () : nullptr;
}
static OT::SubstLookup *
@@ -126,7 +126,7 @@ arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UN
first_glyphs_indirection[num_first_glyphs] = first_glyph_idx;
num_first_glyphs++;
}
- hb_stable_sort (&first_glyphs[0], num_first_glyphs, OT::GlyphID::cmp, &first_glyphs_indirection[0]);
+ hb_stable_sort (&first_glyphs[0], num_first_glyphs, (int(*)(const OT::GlyphID*, const OT::GlyphID *)) OT::GlyphID::cmp, &first_glyphs_indirection[0]);
/* Now that the first-glyphs are sorted, walk again, populate ligatures. */
for (unsigned int i = 0; i < num_first_glyphs; i++)
@@ -153,7 +153,7 @@ arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UN
}
if (!num_ligatures)
- return NULL;
+ return nullptr;
OT::Supplier<OT::GlyphID> first_glyphs_supplier (first_glyphs, num_first_glyphs);
OT::Supplier<unsigned int > ligature_per_first_glyph_count_supplier (ligature_per_first_glyph_count_list, num_first_glyphs);
@@ -177,7 +177,7 @@ arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UN
c.end_serialize ();
/* TODO sanitize the results? */
- return ret ? c.copy<OT::SubstLookup> () : NULL;
+ return ret ? c.copy<OT::SubstLookup> () : nullptr;
}
static OT::SubstLookup *
@@ -237,8 +237,8 @@ arabic_fallback_plan_init_win1256 (arabic_fallback_plan_t *fallback_plan,
return false;
const Manifest &manifest = reinterpret_cast<const Manifest&> (arabic_win1256_gsub_lookups.manifest);
- ASSERT_STATIC (sizeof (arabic_win1256_gsub_lookups.manifestData) / sizeof (ManifestLookup)
- <= ARABIC_FALLBACK_MAX_LOOKUPS);
+ static_assert (sizeof (arabic_win1256_gsub_lookups.manifestData) / sizeof (ManifestLookup)
+ <= ARABIC_FALLBACK_MAX_LOOKUPS, "");
/* TODO sanitize the table? */
unsigned j = 0;
@@ -271,7 +271,7 @@ arabic_fallback_plan_init_unicode (arabic_fallback_plan_t *fallback_plan,
const hb_ot_shape_plan_t *plan,
hb_font_t *font)
{
- ASSERT_STATIC (ARRAY_LENGTH_CONST(arabic_fallback_features) <= ARABIC_FALLBACK_MAX_LOOKUPS);
+ static_assert ((ARRAY_LENGTH_CONST(arabic_fallback_features) <= ARABIC_FALLBACK_MAX_LOOKUPS), "");
unsigned int j = 0;
for (unsigned int i = 0; i < ARRAY_LENGTH(arabic_fallback_features) ; i++)
{
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh
index 736c7f76b3..cd6e4058b5 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh
@@ -6,10 +6,10 @@
*
* on files with these headers:
*
- * # ArabicShaping-9.0.0.txt
- * # Date: 2016-02-24, 22:25:00 GMT [RP]
- * # Blocks-9.0.0.txt
- * # Date: 2016-02-05, 23:48:00 GMT [KW]
+ * # ArabicShaping-10.0.0.txt
+ * # Date: 2017-02-16, 00:00:00 GMT [RP, KW]
+ * # Blocks-10.0.0.txt
+ * # Date: 2017-04-12, 17:30:00 GMT [KW]
* UnicodeData.txt does not have a header.
*/
@@ -72,7 +72,10 @@ static const uint8_t joining_table[] =
/* Mandaic */
/* 0840 */ R,D,D,D,D,D,R,R,D,R,D,D,D,D,D,D,D,D,D,D,R,D,U,U,U,X,X,X,X,X,X,X,
- /* 0860 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
+
+ /* Syriac Supplement */
+
+ /* 0860 */ D,U,D,D,D,D,U,R,D,R,R,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
/* 0880 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
/* Arabic Extended-A */
@@ -130,7 +133,7 @@ static const uint8_t joining_table[] =
/* 1E920 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,
/* 1E940 */ D,D,D,D,
-}; /* Table items: 1214; occupancy: 54% */
+}; /* Table items: 1214; occupancy: 55% */
static unsigned int
@@ -139,28 +142,28 @@ joining_type (hb_codepoint_t u)
switch (u >> 12)
{
case 0x0u:
- if (hb_in_range (u, 0x0600u, 0x08E2u)) return joining_table[u - 0x0600u + joining_offset_0x0600u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x0600u, 0x08E2u)) return joining_table[u - 0x0600u + joining_offset_0x0600u];
break;
case 0x1u:
- if (hb_in_range (u, 0x1806u, 0x18AAu)) return joining_table[u - 0x1806u + joining_offset_0x1806u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x1806u, 0x18AAu)) return joining_table[u - 0x1806u + joining_offset_0x1806u];
break;
case 0x2u:
- if (hb_in_range (u, 0x200Cu, 0x2069u)) return joining_table[u - 0x200Cu + joining_offset_0x200cu];
+ if (hb_in_range<hb_codepoint_t> (u, 0x200Cu, 0x2069u)) return joining_table[u - 0x200Cu + joining_offset_0x200cu];
break;
case 0xAu:
- if (hb_in_range (u, 0xA840u, 0xA873u)) return joining_table[u - 0xA840u + joining_offset_0xa840u];
+ if (hb_in_range<hb_codepoint_t> (u, 0xA840u, 0xA873u)) return joining_table[u - 0xA840u + joining_offset_0xa840u];
break;
case 0x10u:
- if (hb_in_range (u, 0x10AC0u, 0x10AEFu)) return joining_table[u - 0x10AC0u + joining_offset_0x10ac0u];
- if (hb_in_range (u, 0x10B80u, 0x10BAFu)) return joining_table[u - 0x10B80u + joining_offset_0x10b80u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x10AC0u, 0x10AEFu)) return joining_table[u - 0x10AC0u + joining_offset_0x10ac0u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x10B80u, 0x10BAFu)) return joining_table[u - 0x10B80u + joining_offset_0x10b80u];
break;
case 0x1Eu:
- if (hb_in_range (u, 0x1E900u, 0x1E943u)) return joining_table[u - 0x1E900u + joining_offset_0x1e900u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x1E900u, 0x1E943u)) return joining_table[u - 0x1E900u + joining_offset_0x1e900u];
break;
default:
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-win1256.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-win1256.hh
index e70c48f427..54c6cdc24f 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-win1256.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-win1256.hh
@@ -43,16 +43,16 @@
#define OT_TABLE_END }
#define OT_LABEL_START(Name) unsigned char Name[
#define OT_LABEL_END ];
-#define OT_BYTE(u8) +1/*byte*/
-#define OT_USHORT(u16) +2/*bytes*/
+#define OT_UINT8(u8) +1/*byte*/
+#define OT_UINT16(u16) +2/*bytes*/
#else
#undef OT_MEASURE
#define OT_TABLE_START TABLE_NAME = {
#define OT_TABLE_END };
#define OT_LABEL_START(Name) {
#define OT_LABEL_END },
-#define OT_BYTE(u8) (u8),
-#define OT_USHORT(u16) (unsigned char)((u16)>>8), (unsigned char)((u16)&0xFFu),
+#define OT_UINT8(u8) (u8),
+#define OT_UINT16(u16) (unsigned char)((u16)>>8), (unsigned char)((u16)&0xFFu),
#define OT_COUNT(Name, ItemSize) ((unsigned int) sizeof(((struct TABLE_NAME*)0)->Name) \
/ (unsigned int)(ItemSize) \
/* OT_ASSERT it's divisible (and positive). */)
@@ -80,24 +80,24 @@
*/
#define OT_TAG(a,b,c,d) \
- OT_BYTE(a) OT_BYTE(b) OT_BYTE(c) OT_BYTE(d)
+ OT_UINT8(a) OT_UINT8(b) OT_UINT8(c) OT_UINT8(d)
#define OT_OFFSET(From, To) /* Offset from From to To in bytes */ \
- OT_USHORT(OT_DISTANCE(From, To))
+ OT_UINT16(OT_DISTANCE(From, To))
#define OT_GLYPHID /* GlyphID */ \
- OT_USHORT
+ OT_UINT16
#define OT_UARRAY(Name, Items) \
OT_LABEL_START(Name) \
- OT_USHORT(OT_COUNT(Name##Data, 2)) \
+ OT_UINT16(OT_COUNT(Name##Data, 2)) \
OT_LABEL(Name##Data) \
Items \
OT_LABEL_END
#define OT_UHEADLESSARRAY(Name, Items) \
OT_LABEL_START(Name) \
- OT_USHORT(OT_COUNT(Name##Data, 2) + 1) \
+ OT_UINT16(OT_COUNT(Name##Data, 2) + 1) \
OT_LABEL(Name##Data) \
Items \
OT_LABEL_END
@@ -111,19 +111,19 @@
#define OT_LOOKUP(Name, LookupType, LookupFlag, SubLookupOffsets) \
OT_LABEL_START(Name) \
- OT_USHORT(LookupType) \
- OT_USHORT(LookupFlag) \
+ OT_UINT16(LookupType) \
+ OT_UINT16(LookupFlag) \
OT_LABEL_END \
OT_UARRAY(Name##SubLookupOffsetsArray, OT_LIST(SubLookupOffsets))
#define OT_SUBLOOKUP(Name, SubFormat, Items) \
OT_LABEL_START(Name) \
- OT_USHORT(SubFormat) \
+ OT_UINT16(SubFormat) \
Items
#define OT_COVERAGE1(Name, Items) \
OT_LABEL_START(Name) \
- OT_USHORT(1) \
+ OT_UINT16(1) \
OT_LABEL_END \
OT_UARRAY(Name##Glyphs, OT_LIST(Items))
@@ -174,7 +174,7 @@
/* Table manifest. */
#define MANIFEST(Items) \
OT_LABEL_START(manifest) \
- OT_USHORT(OT_COUNT(manifestData, 6)) \
+ OT_UINT16(OT_COUNT(manifestData, 6)) \
OT_LABEL(manifestData) \
Items \
OT_LABEL_END
@@ -304,8 +304,8 @@ OT_TABLE_END
#undef OT_TABLE_END
#undef OT_LABEL_START
#undef OT_LABEL_END
-#undef OT_BYTE
-#undef OT_USHORT
+#undef OT_UINT8
+#undef OT_UINT16
#undef OT_DISTANCE
#undef OT_COUNT
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc
index 56ec5cd65c..eb9d36ff1d 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc
@@ -24,24 +24,21 @@
* Google Author(s): Behdad Esfahbod
*/
+#include "hb-private.hh"
+#include "hb-debug.hh"
#include "hb-ot-shape-complex-arabic-private.hh"
#include "hb-ot-shape-private.hh"
-#ifndef HB_DEBUG_ARABIC
-#define HB_DEBUG_ARABIC (HB_DEBUG+0)
-#endif
-
-
/* buffer var allocations */
#define arabic_shaping_action() complex_var_u8_0() /* arabic shaping action */
#define HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH HB_BUFFER_SCRATCH_FLAG_COMPLEX0
/* See:
- * https://github.com/behdad/harfbuzz/commit/6e6f82b6f3dde0fc6c3c7d991d9ec6cfff57823d#commitcomment-14248516 */
+ * https://github.com/harfbuzz/harfbuzz/commit/6e6f82b6f3dde0fc6c3c7d991d9ec6cfff57823d#commitcomment-14248516 */
#define HB_ARABIC_GENERAL_CATEGORY_IS_WORD(gen_cat) \
- (FLAG_SAFE (gen_cat) & \
+ (FLAG_UNSAFE (gen_cat) & \
(FLAG (HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED) | \
FLAG (HB_UNICODE_GENERAL_CATEGORY_PRIVATE_USE) | \
/*FLAG (HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER) |*/ \
@@ -90,7 +87,7 @@ static unsigned int get_joining_type (hb_codepoint_t u, hb_unicode_general_categ
if (likely (j_type != JOINING_TYPE_X))
return j_type;
- return (FLAG_SAFE(gen_cat) &
+ return (FLAG_UNSAFE(gen_cat) &
(FLAG(HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) |
FLAG(HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) |
FLAG(HB_UNICODE_GENERAL_CATEGORY_FORMAT))
@@ -199,6 +196,9 @@ collect_features_arabic (hb_ot_shape_planner_t *plan)
* work. However, testing shows that rlig and calt are applied
* together for Mongolian in Uniscribe. As such, we only add a
* pause for Arabic, not other scripts.
+ *
+ * A pause after calt is required to make KFGQPC Uthmanic Script HAFS
+ * work correctly. See https://github.com/harfbuzz/harfbuzz/issues/505
*/
map->add_gsub_pause (nuke_joiners);
@@ -209,20 +209,23 @@ collect_features_arabic (hb_ot_shape_planner_t *plan)
map->add_global_bool_feature (HB_TAG('c','c','m','p'));
map->add_global_bool_feature (HB_TAG('l','o','c','l'));
- map->add_gsub_pause (NULL);
+ map->add_gsub_pause (nullptr);
for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++)
{
bool has_fallback = plan->props.script == HB_SCRIPT_ARABIC && !FEATURE_IS_SYRIAC (arabic_features[i]);
map->add_feature (arabic_features[i], 1, has_fallback ? F_HAS_FALLBACK : F_NONE);
- map->add_gsub_pause (NULL);
+ map->add_gsub_pause (nullptr);
}
map->add_feature (HB_TAG('r','l','i','g'), 1, F_GLOBAL|F_HAS_FALLBACK);
if (plan->props.script == HB_SCRIPT_ARABIC)
map->add_gsub_pause (arabic_fallback_shape);
+ /* No pause after rclt. See 98460779bae19e4d64d29461ff154b3527bf8420. */
+ map->add_global_bool_feature (HB_TAG('r','c','l','t'));
map->add_global_bool_feature (HB_TAG('c','a','l','t'));
+ map->add_gsub_pause (nullptr);
/* The spec includes 'cswh'. Earlier versions of Windows
* used to enable this by default, but testing suggests
@@ -232,7 +235,6 @@ collect_features_arabic (hb_ot_shape_planner_t *plan)
* Note that IranNastaliq uses this feature extensively
* to fixup broken glyph sequences. Oh well...
* Test case: U+0643,U+0640,U+0631. */
- //map->add_gsub_pause (NULL);
//map->add_global_bool_feature (HB_TAG('c','s','w','h'));
map->add_global_bool_feature (HB_TAG('m','s','e','t'));
}
@@ -260,7 +262,7 @@ data_create_arabic (const hb_ot_shape_plan_t *plan)
{
arabic_shape_plan_t *arabic_plan = (arabic_shape_plan_t *) calloc (1, sizeof (arabic_shape_plan_t));
if (unlikely (!arabic_plan))
- return NULL;
+ return nullptr;
arabic_plan->do_fallback = plan->props.script == HB_SCRIPT_ARABIC;
arabic_plan->has_stch = !!plan->map.get_1_mask (HB_TAG ('s','t','c','h'));
@@ -316,7 +318,10 @@ arabic_joining (hb_buffer_t *buffer)
const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
if (entry->prev_action != NONE && prev != (unsigned int) -1)
+ {
info[prev].arabic_shaping_action() = entry->prev_action;
+ buffer->unsafe_to_break (prev, i + 1);
+ }
info[i].arabic_shaping_action() = entry->curr_action;
@@ -345,7 +350,7 @@ mongolian_variation_selectors (hb_buffer_t *buffer)
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 1; i < count; i++)
- if (unlikely (hb_in_range (info[i].codepoint, 0x180Bu, 0x180Du)))
+ if (unlikely (hb_in_range<hb_codepoint_t> (info[i].codepoint, 0x180Bu, 0x180Du)))
info[i].arabic_shaping_action() = info[i - 1].arabic_shaping_action();
}
@@ -404,7 +409,7 @@ retry:
{
/* This sucks. We need a font to build the fallback plan... */
fallback_plan = arabic_fallback_plan_create (plan, font);
- if (unlikely (!hb_atomic_ptr_cmpexch (&(const_cast<arabic_shape_plan_t *> (arabic_plan))->fallback_plan, NULL, fallback_plan))) {
+ if (unlikely (!hb_atomic_ptr_cmpexch (&(const_cast<arabic_shape_plan_t *> (arabic_plan))->fallback_plan, nullptr, fallback_plan))) {
arabic_fallback_plan_destroy (fallback_plan);
goto retry;
}
@@ -524,11 +529,11 @@ apply_stch (const hb_ot_shape_plan_t *plan,
}
i++; // Don't touch i again.
- DEBUG_MSG (ARABIC, NULL, "%s stretch at (%d,%d,%d)",
+ DEBUG_MSG (ARABIC, nullptr, "%s stretch at (%d,%d,%d)",
step == MEASURE ? "measuring" : "cutting", context, start, end);
- DEBUG_MSG (ARABIC, NULL, "rest of word: count=%d width %d", start - context, w_total);
- DEBUG_MSG (ARABIC, NULL, "fixed tiles: count=%d width=%d", n_fixed, w_fixed);
- DEBUG_MSG (ARABIC, NULL, "repeating tiles: count=%d width=%d", n_repeating, w_repeating);
+ DEBUG_MSG (ARABIC, nullptr, "rest of word: count=%d width %d", start - context, w_total);
+ DEBUG_MSG (ARABIC, nullptr, "fixed tiles: count=%d width=%d", n_fixed, w_fixed);
+ DEBUG_MSG (ARABIC, nullptr, "repeating tiles: count=%d width=%d", n_repeating, w_repeating);
/* Number of additional times to repeat each repeating tile. */
int n_copies = 0;
@@ -540,7 +545,7 @@ apply_stch (const hb_ot_shape_plan_t *plan,
/* See if we can improve the fit by adding an extra repeat and squeezing them together a bit. */
hb_position_t extra_repeat_overlap = 0;
hb_position_t shortfall = sign * w_remaining - sign * w_repeating * (n_copies + 1);
- if (shortfall > 0)
+ if (shortfall > 0 && n_repeating > 0)
{
++n_copies;
hb_position_t excess = (n_copies + 1) * sign * w_repeating - sign * w_remaining;
@@ -551,10 +556,11 @@ apply_stch (const hb_ot_shape_plan_t *plan,
if (step == MEASURE)
{
extra_glyphs_needed += n_copies * n_repeating;
- DEBUG_MSG (ARABIC, NULL, "will add extra %d copies of repeating tiles", n_copies);
+ DEBUG_MSG (ARABIC, nullptr, "will add extra %d copies of repeating tiles", n_copies);
}
else
{
+ buffer->unsafe_to_break (context, end);
hb_position_t x_offset = 0;
for (unsigned int k = end; k > start; k--)
{
@@ -564,7 +570,7 @@ apply_stch (const hb_ot_shape_plan_t *plan,
if (info[k - 1].arabic_shaping_action() == STCH_REPEATING)
repeat += n_copies;
- DEBUG_MSG (ARABIC, NULL, "appending %d copies of glyph %d; j=%d",
+ DEBUG_MSG (ARABIC, nullptr, "appending %d copies of glyph %d; j=%d",
repeat, info[k - 1].codepoint, j);
for (unsigned int n = 0; n < repeat; n++)
{
@@ -605,20 +611,94 @@ postprocess_glyphs_arabic (const hb_ot_shape_plan_t *plan,
HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
}
+/* http://www.unicode.org/reports/tr53/tr53-1.pdf */
+
+static hb_codepoint_t
+modifier_combining_marks[] =
+{
+ 0x0654u, /* ARABIC HAMZA ABOVE */
+ 0x0655u, /* ARABIC HAMZA BELOW */
+ 0x0658u, /* ARABIC MARK NOON GHUNNA */
+ 0x06DCu, /* ARABIC SMALL HIGH SEEN */
+ 0x06E3u, /* ARABIC SMALL LOW SEEN */
+ 0x06E7u, /* ARABIC SMALL HIGH YEH */
+ 0x06E8u, /* ARABIC SMALL HIGH NOON */
+ 0x08F3u, /* ARABIC SMALL HIGH WAW */
+};
+
+static inline bool
+info_is_mcm (const hb_glyph_info_t &info)
+{
+ hb_codepoint_t u = info.codepoint;
+ for (unsigned int i = 0; i < ARRAY_LENGTH (modifier_combining_marks); i++)
+ if (u == modifier_combining_marks[i])
+ return true;
+ return false;
+}
+
+static void
+reorder_marks_arabic (const hb_ot_shape_plan_t *plan,
+ hb_buffer_t *buffer,
+ unsigned int start,
+ unsigned int end)
+{
+ hb_glyph_info_t *info = buffer->info;
+
+ unsigned int i = start;
+ for (unsigned int cc = 220; cc <= 230; cc += 10)
+ {
+ DEBUG_MSG (ARABIC, buffer, "Looking for %d's starting at %d\n", cc, i);
+ while (i < end && info_cc(info[i]) < cc)
+ i++;
+ DEBUG_MSG (ARABIC, buffer, "Looking for %d's stopped at %d\n", cc, i);
+
+ if (i == end)
+ break;
+
+ if (info_cc(info[i]) > cc)
+ continue;
+
+ /* Technically we should also check "info_cc(info[j]) == cc"
+ * in the following loop. But not doing it is safe; we might
+ * end up moving all the 220 MCMs and 230 MCMs together in one
+ * move and be done. */
+ unsigned int j = i;
+ while (j < end && info_is_mcm (info[j]))
+ j++;
+ DEBUG_MSG (ARABIC, buffer, "Found %d's from %d to %d\n", cc, i, j);
+
+ if (i == j)
+ continue;
+
+ /* Shift it! */
+ DEBUG_MSG (ARABIC, buffer, "Shifting %d's: %d %d\n", cc, i, j);
+ hb_glyph_info_t temp[HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS];
+ assert (j - i <= ARRAY_LENGTH (temp));
+ buffer->merge_clusters (start, j);
+ memmove (temp, &info[i], (j - i) * sizeof (hb_glyph_info_t));
+ memmove (&info[start + j - i], &info[start], (i - start) * sizeof (hb_glyph_info_t));
+ memmove (&info[start], temp, (j - i) * sizeof (hb_glyph_info_t));
+
+ start += j - i;
+
+ i = j;
+ }
+}
+
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic =
{
- "arabic",
collect_features_arabic,
- NULL, /* override_features */
+ nullptr, /* override_features */
data_create_arabic,
data_destroy_arabic,
- NULL, /* preprocess_text */
+ nullptr, /* preprocess_text */
postprocess_glyphs_arabic,
HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
- NULL, /* decompose */
- NULL, /* compose */
+ nullptr, /* decompose */
+ nullptr, /* compose */
setup_masks_arabic,
- NULL, /* disable_otl */
+ nullptr, /* disable_otl */
+ reorder_marks_arabic,
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
true, /* fallback_position */
};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-default.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-default.cc
index 42830ab618..68a62a10d4 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-default.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-default.cc
@@ -29,18 +29,18 @@
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default =
{
- "default",
- NULL, /* collect_features */
- NULL, /* override_features */
- NULL, /* data_create */
- NULL, /* data_destroy */
- NULL, /* preprocess_text */
- NULL, /* postprocess_glyphs */
+ nullptr, /* collect_features */
+ nullptr, /* override_features */
+ nullptr, /* data_create */
+ nullptr, /* data_destroy */
+ nullptr, /* preprocess_text */
+ nullptr, /* postprocess_glyphs */
HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
- NULL, /* decompose */
- NULL, /* compose */
- NULL, /* setup_masks */
- NULL, /* disable_otl */
+ nullptr, /* decompose */
+ nullptr, /* compose */
+ nullptr, /* setup_masks */
+ nullptr, /* disable_otl */
+ nullptr, /* reorder_marks */
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
true, /* fallback_position */
};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc
index eb95a28c09..7508c223c4 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc
@@ -32,7 +32,7 @@
/* Same order as the feature array below */
enum {
- NONE,
+ _JMO,
LJMO,
VJMO,
@@ -80,7 +80,7 @@ data_create_hangul (const hb_ot_shape_plan_t *plan)
{
hangul_shape_plan_t *hangul_plan = (hangul_shape_plan_t *) calloc (1, sizeof (hangul_shape_plan_t));
if (unlikely (!hangul_plan))
- return NULL;
+ return nullptr;
for (unsigned int i = 0; i < HANGUL_FEATURE_COUNT; i++)
hangul_plan->mask_array[i] = plan->map.get_1_mask (hangul_features[i]);
@@ -105,16 +105,16 @@ data_destroy_hangul (void *data)
#define NCount (VCount * TCount)
#define SCount (LCount * NCount)
-#define isCombiningL(u) (hb_in_range ((u), LBase, LBase+LCount-1))
-#define isCombiningV(u) (hb_in_range ((u), VBase, VBase+VCount-1))
-#define isCombiningT(u) (hb_in_range ((u), TBase+1, TBase+TCount-1))
-#define isCombinedS(u) (hb_in_range ((u), SBase, SBase+SCount-1))
+#define isCombiningL(u) (hb_in_range<hb_codepoint_t> ((u), LBase, LBase+LCount-1))
+#define isCombiningV(u) (hb_in_range<hb_codepoint_t> ((u), VBase, VBase+VCount-1))
+#define isCombiningT(u) (hb_in_range<hb_codepoint_t> ((u), TBase+1, TBase+TCount-1))
+#define isCombinedS(u) (hb_in_range<hb_codepoint_t> ((u), SBase, SBase+SCount-1))
-#define isL(u) (hb_in_ranges ((u), 0x1100u, 0x115Fu, 0xA960u, 0xA97Cu))
-#define isV(u) (hb_in_ranges ((u), 0x1160u, 0x11A7u, 0xD7B0u, 0xD7C6u))
-#define isT(u) (hb_in_ranges ((u), 0x11A8u, 0x11FFu, 0xD7CBu, 0xD7FBu))
+#define isL(u) (hb_in_ranges<hb_codepoint_t> ((u), 0x1100u, 0x115Fu, 0xA960u, 0xA97Cu))
+#define isV(u) (hb_in_ranges<hb_codepoint_t> ((u), 0x1160u, 0x11A7u, 0xD7B0u, 0xD7C6u))
+#define isT(u) (hb_in_ranges<hb_codepoint_t> ((u), 0x11A8u, 0x11FFu, 0xD7CBu, 0xD7FBu))
-#define isHangulTone(u) (hb_in_range ((u), 0x302Eu, 0x302Fu))
+#define isHangulTone(u) (hb_in_range<hb_codepoint_t> ((u), 0x302Eu, 0x302Fu))
/* buffer var allocations */
#define hangul_shaping_feature() complex_var_u8_0() /* hangul jamo shaping feature */
@@ -202,6 +202,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan,
if (start < end && end == buffer->out_len)
{
/* Tone mark follows a valid syllable; move it in front, unless it's zero width. */
+ buffer->unsafe_to_break_from_outbuffer (start, buffer->idx);
buffer->next_glyph ();
if (!is_zero_width_char (font, u))
{
@@ -258,6 +259,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan,
else
t = 0; /* The next character was not a trailing jamo. */
}
+ buffer->unsafe_to_break (buffer->idx, buffer->idx + (t ? 3 : 2));
/* We've got a syllable <L,V,T?>; see if it can potentially be composed. */
if (isCombiningL (l) && isCombiningV (v) && (t == 0 || isCombiningT (t)))
@@ -322,6 +324,8 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan,
end = start + 1;
continue;
}
+ else
+ buffer->unsafe_to_break (buffer->idx, buffer->idx + 2); /* Mark unsafe between LV and T. */
}
/* Otherwise, decompose if font doesn't support <LV> or <LVT>,
@@ -368,6 +372,8 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan,
buffer->merge_out_clusters (start, end);
continue;
}
+ else if ((!tindex && buffer->idx + 1 < count && isT (buffer->cur(+1).codepoint)))
+ buffer->unsafe_to_break (buffer->idx, buffer->idx + 2); /* Mark unsafe between LV and T. */
}
if (has_glyph)
@@ -408,18 +414,18 @@ setup_masks_hangul (const hb_ot_shape_plan_t *plan,
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hangul =
{
- "hangul",
collect_features_hangul,
override_features_hangul,
data_create_hangul,
data_destroy_hangul,
preprocess_text_hangul,
- NULL, /* postprocess_glyphs */
+ nullptr, /* postprocess_glyphs */
HB_OT_SHAPE_NORMALIZATION_MODE_NONE,
- NULL, /* decompose */
- NULL, /* compose */
+ nullptr, /* decompose */
+ nullptr, /* compose */
setup_masks_hangul,
- NULL, /* disable_otl */
+ nullptr, /* disable_otl */
+ nullptr, /* reorder_marks */
HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
false, /* fallback_position */
};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hebrew.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hebrew.cc
index 96f2494616..34cf28b8e2 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hebrew.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hebrew.cc
@@ -161,7 +161,7 @@ disable_otl_hebrew (const hb_ot_shape_plan_t *plan)
* script. This matches Uniscribe better, and makes fonts like
* Arial that have GSUB/GPOS/GDEF but no data for Hebrew work.
* See:
- * https://github.com/behdad/harfbuzz/issues/347#issuecomment-267838368
+ * https://github.com/harfbuzz/harfbuzz/issues/347#issuecomment-267838368
*/
return plan->map.chosen_script[1] != HB_TAG ('h','e','b','r');
}
@@ -169,18 +169,18 @@ disable_otl_hebrew (const hb_ot_shape_plan_t *plan)
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hebrew =
{
- "hebrew",
- NULL, /* collect_features */
- NULL, /* override_features */
- NULL, /* data_create */
- NULL, /* data_destroy */
- NULL, /* preprocess_text */
- NULL, /* postprocess_glyphs */
+ nullptr, /* collect_features */
+ nullptr, /* override_features */
+ nullptr, /* data_create */
+ nullptr, /* data_destroy */
+ nullptr, /* preprocess_text */
+ nullptr, /* postprocess_glyphs */
HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
- NULL, /* decompose */
+ nullptr, /* decompose */
compose_hebrew,
- NULL, /* setup_masks */
+ nullptr, /* setup_masks */
disable_otl_hebrew,
+ nullptr, /* reorder_marks */
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
true, /* fallback_position */
};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh
index 5a7a265c87..7eaba4e4e7 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh
@@ -56,7 +56,7 @@ static const unsigned char _indic_syllable_machine_trans_keys[] = {
5u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u,
5u, 7u, 7u, 7u, 8u, 8u, 1u, 16u, 8u, 13u, 4u, 8u, 6u, 6u, 16u, 16u,
4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u,
- 16u, 16u, 8u, 8u, 1u, 18u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u,
+ 16u, 16u, 8u, 8u, 1u, 19u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u,
3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u,
3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 5u, 14u, 5u, 14u,
5u, 10u, 9u, 10u, 9u, 9u, 9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 3u, 13u,
@@ -101,7 +101,7 @@ static const unsigned char _indic_syllable_machine_trans_keys[] = {
3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u,
5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 13u, 3u, 10u, 5u, 10u, 3u, 10u,
3u, 13u, 1u, 16u, 3u, 10u, 5u, 10u, 5u, 10u, 9u, 10u, 9u, 9u, 9u, 10u,
- 9u, 10u, 9u, 9u, 5u, 10u, 0
+ 9u, 10u, 9u, 9u, 5u, 10u, 1u, 16u, 0
};
static const char _indic_syllable_machine_key_spans[] = {
@@ -127,7 +127,7 @@ static const char _indic_syllable_machine_key_spans[] = {
3, 4, 3, 1, 4, 3, 1, 4,
3, 1, 1, 16, 6, 5, 1, 1,
5, 1, 1, 5, 1, 1, 5, 1,
- 1, 1, 18, 15, 15, 14, 16, 15,
+ 1, 1, 19, 15, 15, 14, 16, 15,
15, 14, 16, 15, 15, 14, 16, 15,
15, 14, 16, 15, 15, 14, 10, 10,
6, 2, 1, 2, 2, 1, 6, 11,
@@ -172,7 +172,7 @@ static const char _indic_syllable_machine_key_spans[] = {
12, 11, 10, 12, 11, 10, 12, 11,
10, 12, 11, 10, 11, 8, 6, 8,
11, 16, 8, 6, 6, 2, 1, 2,
- 2, 1, 6
+ 2, 1, 6, 16
};
static const short _indic_syllable_machine_index_offsets[] = {
@@ -198,52 +198,52 @@ static const short _indic_syllable_machine_index_offsets[] = {
954, 958, 963, 967, 969, 974, 978, 980,
985, 989, 991, 993, 1010, 1017, 1023, 1025,
1027, 1033, 1035, 1037, 1043, 1045, 1047, 1053,
- 1055, 1057, 1059, 1078, 1094, 1110, 1125, 1142,
- 1158, 1174, 1189, 1206, 1222, 1238, 1253, 1270,
- 1286, 1302, 1317, 1334, 1350, 1366, 1381, 1392,
- 1403, 1410, 1413, 1415, 1418, 1421, 1423, 1430,
- 1442, 1451, 1458, 1467, 1479, 1492, 1505, 1517,
- 1528, 1541, 1553, 1564, 1577, 1589, 1600, 1613,
- 1625, 1636, 1649, 1666, 1678, 1694, 1710, 1727,
- 1744, 1761, 1778, 1795, 1811, 1827, 1844, 1861,
- 1878, 1895, 1912, 1928, 1944, 1961, 1978, 1995,
- 2012, 2029, 2045, 2061, 2078, 2095, 2112, 2129,
- 2146, 2162, 2178, 2194, 2210, 2225, 2242, 2258,
- 2274, 2289, 2306, 2322, 2338, 2353, 2370, 2386,
- 2402, 2417, 2434, 2450, 2466, 2481, 2492, 2503,
- 2510, 2513, 2515, 2518, 2521, 2523, 2530, 2542,
- 2551, 2558, 2567, 2579, 2592, 2605, 2617, 2628,
- 2641, 2653, 2664, 2677, 2689, 2700, 2713, 2725,
- 2736, 2749, 2766, 2778, 2794, 2810, 2827, 2844,
- 2861, 2878, 2895, 2911, 2927, 2944, 2961, 2978,
- 2995, 3012, 3028, 3044, 3061, 3078, 3095, 3112,
- 3129, 3145, 3161, 3178, 3195, 3212, 3229, 3241,
- 3258, 3274, 3290, 3305, 3322, 3338, 3354, 3369,
- 3386, 3402, 3418, 3433, 3450, 3466, 3482, 3497,
- 3514, 3530, 3546, 3561, 3572, 3583, 3590, 3593,
- 3595, 3598, 3601, 3603, 3610, 3622, 3631, 3638,
- 3647, 3659, 3672, 3685, 3697, 3708, 3721, 3733,
- 3744, 3757, 3769, 3780, 3793, 3805, 3816, 3829,
- 3846, 3858, 3874, 3890, 3907, 3924, 3941, 3958,
- 3975, 3991, 4007, 4024, 4041, 4058, 4075, 4092,
- 4108, 4124, 4141, 4158, 4175, 4192, 4209, 4225,
- 4241, 4258, 4275, 4292, 4309, 4326, 4338, 4354,
- 4366, 4382, 4398, 4413, 4430, 4446, 4462, 4477,
- 4494, 4510, 4526, 4541, 4558, 4574, 4590, 4605,
- 4622, 4638, 4654, 4669, 4680, 4691, 4698, 4701,
- 4703, 4706, 4709, 4711, 4718, 4730, 4739, 4746,
- 4755, 4767, 4780, 4793, 4805, 4816, 4829, 4841,
- 4852, 4865, 4877, 4888, 4901, 4913, 4924, 4937,
- 4954, 4966, 4982, 4998, 5015, 5032, 5049, 5066,
- 5083, 5099, 5115, 5132, 5149, 5166, 5183, 5200,
- 5216, 5232, 5249, 5266, 5283, 5300, 5317, 5333,
- 5349, 5366, 5383, 5400, 5417, 5434, 5450, 5468,
- 5484, 5502, 5514, 5521, 5524, 5526, 5529, 5532,
- 5534, 5541, 5558, 5574, 5590, 5605, 5621, 5637,
- 5654, 5667, 5679, 5690, 5703, 5715, 5726, 5739,
- 5751, 5762, 5775, 5787, 5798, 5810, 5819, 5826,
- 5835, 5847, 5864, 5873, 5880, 5887, 5890, 5892,
- 5895, 5898, 5900
+ 1055, 1057, 1059, 1079, 1095, 1111, 1126, 1143,
+ 1159, 1175, 1190, 1207, 1223, 1239, 1254, 1271,
+ 1287, 1303, 1318, 1335, 1351, 1367, 1382, 1393,
+ 1404, 1411, 1414, 1416, 1419, 1422, 1424, 1431,
+ 1443, 1452, 1459, 1468, 1480, 1493, 1506, 1518,
+ 1529, 1542, 1554, 1565, 1578, 1590, 1601, 1614,
+ 1626, 1637, 1650, 1667, 1679, 1695, 1711, 1728,
+ 1745, 1762, 1779, 1796, 1812, 1828, 1845, 1862,
+ 1879, 1896, 1913, 1929, 1945, 1962, 1979, 1996,
+ 2013, 2030, 2046, 2062, 2079, 2096, 2113, 2130,
+ 2147, 2163, 2179, 2195, 2211, 2226, 2243, 2259,
+ 2275, 2290, 2307, 2323, 2339, 2354, 2371, 2387,
+ 2403, 2418, 2435, 2451, 2467, 2482, 2493, 2504,
+ 2511, 2514, 2516, 2519, 2522, 2524, 2531, 2543,
+ 2552, 2559, 2568, 2580, 2593, 2606, 2618, 2629,
+ 2642, 2654, 2665, 2678, 2690, 2701, 2714, 2726,
+ 2737, 2750, 2767, 2779, 2795, 2811, 2828, 2845,
+ 2862, 2879, 2896, 2912, 2928, 2945, 2962, 2979,
+ 2996, 3013, 3029, 3045, 3062, 3079, 3096, 3113,
+ 3130, 3146, 3162, 3179, 3196, 3213, 3230, 3242,
+ 3259, 3275, 3291, 3306, 3323, 3339, 3355, 3370,
+ 3387, 3403, 3419, 3434, 3451, 3467, 3483, 3498,
+ 3515, 3531, 3547, 3562, 3573, 3584, 3591, 3594,
+ 3596, 3599, 3602, 3604, 3611, 3623, 3632, 3639,
+ 3648, 3660, 3673, 3686, 3698, 3709, 3722, 3734,
+ 3745, 3758, 3770, 3781, 3794, 3806, 3817, 3830,
+ 3847, 3859, 3875, 3891, 3908, 3925, 3942, 3959,
+ 3976, 3992, 4008, 4025, 4042, 4059, 4076, 4093,
+ 4109, 4125, 4142, 4159, 4176, 4193, 4210, 4226,
+ 4242, 4259, 4276, 4293, 4310, 4327, 4339, 4355,
+ 4367, 4383, 4399, 4414, 4431, 4447, 4463, 4478,
+ 4495, 4511, 4527, 4542, 4559, 4575, 4591, 4606,
+ 4623, 4639, 4655, 4670, 4681, 4692, 4699, 4702,
+ 4704, 4707, 4710, 4712, 4719, 4731, 4740, 4747,
+ 4756, 4768, 4781, 4794, 4806, 4817, 4830, 4842,
+ 4853, 4866, 4878, 4889, 4902, 4914, 4925, 4938,
+ 4955, 4967, 4983, 4999, 5016, 5033, 5050, 5067,
+ 5084, 5100, 5116, 5133, 5150, 5167, 5184, 5201,
+ 5217, 5233, 5250, 5267, 5284, 5301, 5318, 5334,
+ 5350, 5367, 5384, 5401, 5418, 5435, 5451, 5469,
+ 5485, 5503, 5515, 5522, 5525, 5527, 5530, 5533,
+ 5535, 5542, 5559, 5575, 5591, 5606, 5622, 5638,
+ 5655, 5668, 5680, 5691, 5704, 5716, 5727, 5740,
+ 5752, 5763, 5776, 5788, 5799, 5811, 5820, 5827,
+ 5836, 5848, 5865, 5874, 5881, 5888, 5891, 5893,
+ 5896, 5899, 5901, 5908
};
static const short _indic_syllable_machine_indicies[] = {
@@ -381,611 +381,613 @@ static const short _indic_syllable_machine_indicies[] = {
161, 161, 162, 157, 0, 183, 0, 184,
0, 186, 185, 188, 189, 190, 191, 192,
193, 84, 79, 194, 195, 196, 196, 156,
- 197, 198, 199, 200, 201, 187, 203, 204,
- 205, 206, 6, 1, 207, 208, 202, 202,
- 38, 209, 202, 202, 210, 202, 211, 204,
- 212, 212, 6, 1, 207, 208, 202, 202,
- 202, 209, 202, 202, 210, 202, 204, 212,
- 212, 6, 1, 207, 208, 202, 202, 202,
- 209, 202, 202, 210, 202, 213, 202, 202,
- 202, 19, 214, 202, 1, 207, 208, 202,
- 202, 202, 215, 202, 213, 202, 216, 217,
- 218, 219, 6, 1, 207, 208, 202, 202,
- 36, 220, 202, 202, 210, 202, 221, 217,
- 222, 222, 6, 1, 207, 208, 202, 202,
- 202, 220, 202, 202, 210, 202, 217, 222,
- 222, 6, 1, 207, 208, 202, 202, 202,
- 220, 202, 202, 210, 202, 223, 202, 202,
- 202, 19, 224, 202, 1, 207, 208, 202,
- 202, 202, 215, 202, 223, 202, 225, 226,
- 227, 228, 6, 1, 207, 208, 202, 202,
- 34, 229, 202, 202, 210, 202, 230, 226,
- 231, 231, 6, 1, 207, 208, 202, 202,
- 202, 229, 202, 202, 210, 202, 226, 231,
- 231, 6, 1, 207, 208, 202, 202, 202,
- 229, 202, 202, 210, 202, 232, 202, 202,
- 202, 19, 233, 202, 1, 207, 208, 202,
- 202, 202, 215, 202, 232, 202, 234, 235,
- 236, 237, 6, 1, 207, 208, 202, 202,
- 32, 238, 202, 202, 210, 202, 239, 235,
- 240, 240, 6, 1, 207, 208, 202, 202,
- 202, 238, 202, 202, 210, 202, 235, 240,
- 240, 6, 1, 207, 208, 202, 202, 202,
- 238, 202, 202, 210, 202, 241, 202, 202,
- 202, 19, 242, 202, 1, 207, 208, 202,
- 202, 202, 215, 202, 241, 202, 243, 244,
- 245, 246, 6, 1, 207, 208, 202, 202,
- 30, 247, 202, 202, 210, 202, 248, 244,
- 249, 249, 6, 1, 207, 208, 202, 202,
- 202, 247, 202, 202, 210, 202, 244, 249,
- 249, 6, 1, 207, 208, 202, 202, 202,
- 247, 202, 202, 210, 202, 19, 250, 202,
- 1, 207, 208, 202, 202, 202, 215, 202,
- 251, 251, 202, 1, 207, 208, 202, 202,
- 202, 215, 202, 252, 202, 202, 253, 207,
- 208, 202, 207, 208, 202, 254, 202, 207,
- 255, 202, 207, 256, 202, 207, 202, 252,
- 202, 202, 202, 207, 208, 202, 257, 202,
- 258, 259, 202, 1, 207, 208, 202, 202,
- 4, 202, 3, 202, 251, 251, 202, 1,
- 207, 208, 202, 251, 251, 202, 1, 207,
- 208, 202, 257, 202, 251, 251, 202, 1,
- 207, 208, 202, 257, 202, 258, 251, 202,
- 1, 207, 208, 202, 202, 4, 202, 19,
- 202, 260, 260, 6, 1, 207, 208, 202,
- 202, 202, 215, 202, 261, 28, 262, 263,
- 9, 1, 207, 208, 202, 202, 202, 215,
- 202, 28, 262, 263, 9, 1, 207, 208,
- 202, 202, 202, 215, 202, 262, 262, 9,
- 1, 207, 208, 202, 202, 202, 215, 202,
- 264, 25, 265, 266, 12, 1, 207, 208,
- 202, 202, 202, 215, 202, 25, 265, 266,
- 12, 1, 207, 208, 202, 202, 202, 215,
- 202, 265, 265, 12, 1, 207, 208, 202,
- 202, 202, 215, 202, 267, 22, 268, 269,
- 15, 1, 207, 208, 202, 202, 202, 215,
- 202, 22, 268, 269, 15, 1, 207, 208,
- 202, 202, 202, 215, 202, 268, 268, 15,
- 1, 207, 208, 202, 202, 202, 215, 202,
- 270, 19, 251, 271, 202, 1, 207, 208,
- 202, 202, 202, 215, 202, 19, 251, 271,
- 202, 1, 207, 208, 202, 202, 202, 215,
- 202, 251, 272, 202, 1, 207, 208, 202,
- 202, 202, 215, 202, 19, 202, 251, 251,
- 202, 1, 207, 208, 202, 202, 202, 215,
- 202, 2, 3, 202, 202, 19, 250, 202,
- 1, 207, 208, 202, 202, 202, 215, 202,
- 2, 202, 244, 249, 249, 6, 1, 207,
- 208, 202, 202, 202, 247, 202, 243, 244,
- 249, 249, 6, 1, 207, 208, 202, 202,
- 202, 247, 202, 202, 210, 202, 243, 244,
- 245, 249, 6, 1, 207, 208, 202, 202,
- 30, 247, 202, 202, 210, 202, 241, 202,
- 273, 202, 260, 260, 6, 1, 207, 208,
- 202, 202, 202, 215, 202, 241, 202, 241,
- 202, 202, 202, 251, 251, 202, 1, 207,
- 208, 202, 202, 202, 215, 202, 241, 202,
- 241, 202, 202, 202, 251, 274, 202, 1,
- 207, 208, 202, 202, 202, 215, 202, 241,
- 202, 241, 202, 273, 202, 251, 251, 202,
- 1, 207, 208, 202, 202, 202, 215, 202,
- 241, 202, 241, 3, 202, 202, 19, 242,
- 202, 1, 207, 208, 202, 202, 202, 215,
- 202, 241, 202, 234, 235, 240, 240, 6,
- 1, 207, 208, 202, 202, 202, 238, 202,
- 202, 210, 202, 234, 235, 236, 240, 6,
- 1, 207, 208, 202, 202, 32, 238, 202,
- 202, 210, 202, 232, 202, 275, 202, 260,
- 260, 6, 1, 207, 208, 202, 202, 202,
- 215, 202, 232, 202, 232, 202, 202, 202,
- 251, 251, 202, 1, 207, 208, 202, 202,
- 202, 215, 202, 232, 202, 232, 202, 202,
- 202, 251, 276, 202, 1, 207, 208, 202,
- 202, 202, 215, 202, 232, 202, 232, 202,
- 275, 202, 251, 251, 202, 1, 207, 208,
- 202, 202, 202, 215, 202, 232, 202, 232,
- 3, 202, 202, 19, 233, 202, 1, 207,
- 208, 202, 202, 202, 215, 202, 232, 202,
- 225, 226, 231, 231, 6, 1, 207, 208,
- 202, 202, 202, 229, 202, 202, 210, 202,
- 225, 226, 227, 231, 6, 1, 207, 208,
- 202, 202, 34, 229, 202, 202, 210, 202,
- 223, 202, 277, 202, 260, 260, 6, 1,
- 207, 208, 202, 202, 202, 215, 202, 223,
- 202, 223, 202, 202, 202, 251, 251, 202,
- 1, 207, 208, 202, 202, 202, 215, 202,
- 223, 202, 223, 202, 202, 202, 251, 278,
- 202, 1, 207, 208, 202, 202, 202, 215,
- 202, 223, 202, 223, 202, 277, 202, 251,
- 251, 202, 1, 207, 208, 202, 202, 202,
- 215, 202, 223, 202, 223, 3, 202, 202,
- 19, 224, 202, 1, 207, 208, 202, 202,
- 202, 215, 202, 223, 202, 216, 217, 222,
- 222, 6, 1, 207, 208, 202, 202, 202,
- 220, 202, 202, 210, 202, 216, 217, 218,
- 222, 6, 1, 207, 208, 202, 202, 36,
- 220, 202, 202, 210, 202, 213, 202, 279,
- 202, 260, 260, 6, 1, 207, 208, 202,
- 202, 202, 215, 202, 213, 202, 213, 202,
- 202, 202, 251, 251, 202, 1, 207, 208,
- 202, 202, 202, 215, 202, 213, 202, 213,
- 202, 202, 202, 251, 280, 202, 1, 207,
- 208, 202, 202, 202, 215, 202, 213, 202,
- 213, 202, 279, 202, 251, 251, 202, 1,
- 207, 208, 202, 202, 202, 215, 202, 213,
- 202, 213, 3, 202, 202, 19, 214, 202,
- 1, 207, 208, 202, 202, 202, 215, 202,
- 213, 202, 203, 204, 212, 212, 6, 1,
- 207, 208, 202, 202, 202, 209, 202, 202,
- 210, 202, 203, 204, 205, 212, 6, 1,
- 207, 208, 202, 202, 38, 209, 202, 202,
- 210, 202, 282, 283, 284, 285, 45, 40,
- 286, 287, 281, 281, 77, 288, 281, 281,
- 289, 281, 290, 283, 291, 285, 45, 40,
- 286, 287, 281, 281, 281, 288, 281, 281,
- 289, 281, 283, 291, 285, 45, 40, 286,
- 287, 281, 281, 281, 288, 281, 281, 289,
- 281, 292, 281, 281, 281, 58, 293, 281,
- 40, 286, 287, 281, 281, 281, 294, 281,
- 292, 281, 295, 296, 297, 298, 45, 40,
- 286, 287, 281, 281, 75, 299, 281, 281,
- 289, 281, 300, 296, 301, 301, 45, 40,
- 286, 287, 281, 281, 281, 299, 281, 281,
- 289, 281, 296, 301, 301, 45, 40, 286,
- 287, 281, 281, 281, 299, 281, 281, 289,
- 281, 302, 281, 281, 281, 58, 303, 281,
- 40, 286, 287, 281, 281, 281, 294, 281,
- 302, 281, 304, 305, 306, 307, 45, 40,
- 286, 287, 281, 281, 73, 308, 281, 281,
- 289, 281, 309, 305, 310, 310, 45, 40,
- 286, 287, 281, 281, 281, 308, 281, 281,
- 289, 281, 305, 310, 310, 45, 40, 286,
- 287, 281, 281, 281, 308, 281, 281, 289,
- 281, 311, 281, 281, 281, 58, 312, 281,
- 40, 286, 287, 281, 281, 281, 294, 281,
- 311, 281, 313, 314, 315, 316, 45, 40,
- 286, 287, 281, 281, 71, 317, 281, 281,
- 289, 281, 318, 314, 319, 319, 45, 40,
- 286, 287, 281, 281, 281, 317, 281, 281,
- 289, 281, 314, 319, 319, 45, 40, 286,
- 287, 281, 281, 281, 317, 281, 281, 289,
- 281, 320, 281, 281, 281, 58, 321, 281,
- 40, 286, 287, 281, 281, 281, 294, 281,
- 320, 281, 322, 323, 324, 325, 45, 40,
- 286, 287, 281, 281, 69, 326, 281, 281,
- 289, 281, 327, 323, 328, 328, 45, 40,
- 286, 287, 281, 281, 281, 326, 281, 281,
- 289, 281, 323, 328, 328, 45, 40, 286,
- 287, 281, 281, 281, 326, 281, 281, 289,
- 281, 58, 329, 281, 40, 286, 287, 281,
- 281, 281, 294, 281, 330, 330, 281, 40,
- 286, 287, 281, 281, 281, 294, 281, 331,
- 281, 281, 332, 286, 287, 281, 286, 287,
- 281, 333, 281, 286, 334, 281, 286, 335,
- 281, 286, 281, 331, 281, 281, 281, 286,
- 287, 281, 336, 281, 337, 338, 281, 40,
- 286, 287, 281, 281, 43, 281, 42, 281,
- 330, 330, 281, 40, 286, 287, 281, 330,
- 330, 281, 40, 286, 287, 281, 336, 281,
- 330, 330, 281, 40, 286, 287, 281, 336,
- 281, 337, 330, 281, 40, 286, 287, 281,
- 281, 43, 281, 58, 281, 339, 339, 45,
- 40, 286, 287, 281, 281, 281, 294, 281,
- 340, 67, 341, 342, 48, 40, 286, 287,
- 281, 281, 281, 294, 281, 67, 341, 342,
- 48, 40, 286, 287, 281, 281, 281, 294,
- 281, 341, 341, 48, 40, 286, 287, 281,
- 281, 281, 294, 281, 343, 64, 344, 345,
- 51, 40, 286, 287, 281, 281, 281, 294,
- 281, 64, 344, 345, 51, 40, 286, 287,
- 281, 281, 281, 294, 281, 344, 344, 51,
- 40, 286, 287, 281, 281, 281, 294, 281,
- 346, 61, 347, 348, 54, 40, 286, 287,
- 281, 281, 281, 294, 281, 61, 347, 348,
- 54, 40, 286, 287, 281, 281, 281, 294,
- 281, 347, 347, 54, 40, 286, 287, 281,
- 281, 281, 294, 281, 349, 58, 330, 350,
- 281, 40, 286, 287, 281, 281, 281, 294,
- 281, 58, 330, 350, 281, 40, 286, 287,
- 281, 281, 281, 294, 281, 330, 351, 281,
- 40, 286, 287, 281, 281, 281, 294, 281,
- 58, 281, 330, 330, 281, 40, 286, 287,
- 281, 281, 281, 294, 281, 41, 42, 281,
- 281, 58, 329, 281, 40, 286, 287, 281,
- 281, 281, 294, 281, 41, 281, 323, 328,
- 328, 45, 40, 286, 287, 281, 281, 281,
- 326, 281, 322, 323, 328, 328, 45, 40,
- 286, 287, 281, 281, 281, 326, 281, 281,
- 289, 281, 322, 323, 324, 328, 45, 40,
- 286, 287, 281, 281, 69, 326, 281, 281,
- 289, 281, 320, 281, 352, 281, 339, 339,
- 45, 40, 286, 287, 281, 281, 281, 294,
- 281, 320, 281, 320, 281, 281, 281, 330,
- 330, 281, 40, 286, 287, 281, 281, 281,
- 294, 281, 320, 281, 320, 281, 281, 281,
- 330, 353, 281, 40, 286, 287, 281, 281,
- 281, 294, 281, 320, 281, 320, 281, 352,
- 281, 330, 330, 281, 40, 286, 287, 281,
- 281, 281, 294, 281, 320, 281, 320, 42,
- 281, 281, 58, 321, 281, 40, 286, 287,
- 281, 281, 281, 294, 281, 320, 281, 313,
- 314, 319, 319, 45, 40, 286, 287, 281,
- 281, 281, 317, 281, 281, 289, 281, 313,
- 314, 315, 319, 45, 40, 286, 287, 281,
- 281, 71, 317, 281, 281, 289, 281, 311,
- 281, 354, 281, 339, 339, 45, 40, 286,
- 287, 281, 281, 281, 294, 281, 311, 281,
- 311, 281, 281, 281, 330, 330, 281, 40,
- 286, 287, 281, 281, 281, 294, 281, 311,
- 281, 311, 281, 281, 281, 330, 355, 281,
- 40, 286, 287, 281, 281, 281, 294, 281,
- 311, 281, 311, 281, 354, 281, 330, 330,
- 281, 40, 286, 287, 281, 281, 281, 294,
- 281, 311, 281, 311, 42, 281, 281, 58,
- 312, 281, 40, 286, 287, 281, 281, 281,
- 294, 281, 311, 281, 304, 305, 310, 310,
- 45, 40, 286, 287, 281, 281, 281, 308,
- 281, 281, 289, 281, 304, 305, 306, 310,
- 45, 40, 286, 287, 281, 281, 73, 308,
- 281, 281, 289, 281, 302, 281, 356, 281,
- 339, 339, 45, 40, 286, 287, 281, 281,
- 281, 294, 281, 302, 281, 302, 281, 281,
- 281, 330, 330, 281, 40, 286, 287, 281,
- 281, 281, 294, 281, 302, 281, 302, 281,
- 281, 281, 330, 357, 281, 40, 286, 287,
- 281, 281, 281, 294, 281, 302, 281, 302,
- 281, 356, 281, 330, 330, 281, 40, 286,
- 287, 281, 281, 281, 294, 281, 302, 281,
- 302, 42, 281, 281, 58, 303, 281, 40,
- 286, 287, 281, 281, 281, 294, 281, 302,
- 281, 295, 296, 301, 301, 45, 40, 286,
- 287, 281, 281, 281, 299, 281, 281, 289,
- 281, 295, 296, 297, 301, 45, 40, 286,
- 287, 281, 281, 75, 299, 281, 281, 289,
- 281, 292, 281, 358, 281, 339, 339, 45,
- 40, 286, 287, 281, 281, 281, 294, 281,
- 292, 281, 292, 281, 281, 281, 330, 330,
- 281, 40, 286, 287, 281, 281, 281, 294,
- 281, 292, 281, 292, 281, 281, 281, 330,
- 359, 281, 40, 286, 287, 281, 281, 281,
- 294, 281, 292, 281, 292, 281, 358, 281,
- 330, 330, 281, 40, 286, 287, 281, 281,
- 281, 294, 281, 292, 281, 76, 44, 44,
- 45, 40, 281, 281, 281, 281, 281, 76,
- 281, 292, 42, 281, 281, 58, 293, 281,
- 40, 286, 287, 281, 281, 281, 294, 281,
- 292, 281, 282, 283, 291, 285, 45, 40,
- 286, 287, 281, 281, 281, 288, 281, 281,
- 289, 281, 361, 191, 362, 362, 84, 79,
- 194, 195, 360, 360, 360, 197, 360, 360,
- 200, 360, 191, 362, 362, 84, 79, 194,
- 195, 360, 360, 360, 197, 360, 360, 200,
- 360, 363, 360, 360, 360, 98, 364, 360,
- 79, 194, 195, 360, 360, 360, 365, 360,
- 363, 360, 366, 367, 368, 369, 84, 79,
- 194, 195, 360, 360, 115, 370, 360, 360,
- 200, 360, 371, 367, 372, 372, 84, 79,
- 194, 195, 360, 360, 360, 370, 360, 360,
- 200, 360, 367, 372, 372, 84, 79, 194,
- 195, 360, 360, 360, 370, 360, 360, 200,
- 360, 373, 360, 360, 360, 98, 374, 360,
- 79, 194, 195, 360, 360, 360, 365, 360,
- 373, 360, 375, 376, 377, 378, 84, 79,
- 194, 195, 360, 360, 113, 379, 360, 360,
- 200, 360, 380, 376, 381, 381, 84, 79,
- 194, 195, 360, 360, 360, 379, 360, 360,
- 200, 360, 376, 381, 381, 84, 79, 194,
- 195, 360, 360, 360, 379, 360, 360, 200,
- 360, 382, 360, 360, 360, 98, 383, 360,
- 79, 194, 195, 360, 360, 360, 365, 360,
- 382, 360, 384, 385, 386, 387, 84, 79,
- 194, 195, 360, 360, 111, 388, 360, 360,
- 200, 360, 389, 385, 390, 390, 84, 79,
- 194, 195, 360, 360, 360, 388, 360, 360,
- 200, 360, 385, 390, 390, 84, 79, 194,
- 195, 360, 360, 360, 388, 360, 360, 200,
- 360, 391, 360, 360, 360, 98, 392, 360,
- 79, 194, 195, 360, 360, 360, 365, 360,
- 391, 360, 393, 394, 395, 396, 84, 79,
- 194, 195, 360, 360, 109, 397, 360, 360,
- 200, 360, 398, 394, 399, 399, 84, 79,
- 194, 195, 360, 360, 360, 397, 360, 360,
- 200, 360, 394, 399, 399, 84, 79, 194,
- 195, 360, 360, 360, 397, 360, 360, 200,
- 360, 98, 400, 360, 79, 194, 195, 360,
- 360, 360, 365, 360, 401, 401, 360, 79,
- 194, 195, 360, 360, 360, 365, 360, 402,
- 360, 360, 403, 194, 195, 360, 194, 195,
- 360, 404, 360, 194, 405, 360, 194, 406,
- 360, 194, 360, 402, 360, 360, 360, 194,
- 195, 360, 407, 360, 408, 409, 360, 79,
- 194, 195, 360, 360, 82, 360, 81, 360,
- 401, 401, 360, 79, 194, 195, 360, 401,
- 401, 360, 79, 194, 195, 360, 407, 360,
- 401, 401, 360, 79, 194, 195, 360, 407,
- 360, 408, 401, 360, 79, 194, 195, 360,
- 360, 82, 360, 98, 360, 410, 410, 84,
- 79, 194, 195, 360, 360, 360, 365, 360,
- 411, 107, 412, 413, 88, 79, 194, 195,
- 360, 360, 360, 365, 360, 107, 412, 413,
- 88, 79, 194, 195, 360, 360, 360, 365,
- 360, 412, 412, 88, 79, 194, 195, 360,
- 360, 360, 365, 360, 414, 104, 415, 416,
- 91, 79, 194, 195, 360, 360, 360, 365,
- 360, 104, 415, 416, 91, 79, 194, 195,
- 360, 360, 360, 365, 360, 415, 415, 91,
- 79, 194, 195, 360, 360, 360, 365, 360,
- 417, 101, 418, 419, 94, 79, 194, 195,
- 360, 360, 360, 365, 360, 101, 418, 419,
- 94, 79, 194, 195, 360, 360, 360, 365,
- 360, 418, 418, 94, 79, 194, 195, 360,
- 360, 360, 365, 360, 420, 98, 401, 421,
- 360, 79, 194, 195, 360, 360, 360, 365,
- 360, 98, 401, 421, 360, 79, 194, 195,
- 360, 360, 360, 365, 360, 401, 422, 360,
- 79, 194, 195, 360, 360, 360, 365, 360,
- 98, 360, 401, 401, 360, 79, 194, 195,
- 360, 360, 360, 365, 360, 80, 81, 360,
- 360, 98, 400, 360, 79, 194, 195, 360,
- 360, 360, 365, 360, 80, 360, 394, 399,
- 399, 84, 79, 194, 195, 360, 360, 360,
- 397, 360, 393, 394, 399, 399, 84, 79,
- 194, 195, 360, 360, 360, 397, 360, 360,
- 200, 360, 393, 394, 395, 399, 84, 79,
- 194, 195, 360, 360, 109, 397, 360, 360,
- 200, 360, 391, 360, 423, 360, 410, 410,
- 84, 79, 194, 195, 360, 360, 360, 365,
- 360, 391, 360, 391, 360, 360, 360, 401,
- 401, 360, 79, 194, 195, 360, 360, 360,
- 365, 360, 391, 360, 391, 360, 360, 360,
- 401, 424, 360, 79, 194, 195, 360, 360,
- 360, 365, 360, 391, 360, 391, 360, 423,
- 360, 401, 401, 360, 79, 194, 195, 360,
- 360, 360, 365, 360, 391, 360, 391, 81,
- 360, 360, 98, 392, 360, 79, 194, 195,
- 360, 360, 360, 365, 360, 391, 360, 384,
- 385, 390, 390, 84, 79, 194, 195, 360,
- 360, 360, 388, 360, 360, 200, 360, 384,
- 385, 386, 390, 84, 79, 194, 195, 360,
- 360, 111, 388, 360, 360, 200, 360, 382,
- 360, 425, 360, 410, 410, 84, 79, 194,
- 195, 360, 360, 360, 365, 360, 382, 360,
- 382, 360, 360, 360, 401, 401, 360, 79,
- 194, 195, 360, 360, 360, 365, 360, 382,
- 360, 382, 360, 360, 360, 401, 426, 360,
- 79, 194, 195, 360, 360, 360, 365, 360,
- 382, 360, 382, 360, 425, 360, 401, 401,
- 360, 79, 194, 195, 360, 360, 360, 365,
- 360, 382, 360, 382, 81, 360, 360, 98,
- 383, 360, 79, 194, 195, 360, 360, 360,
- 365, 360, 382, 360, 375, 376, 381, 381,
- 84, 79, 194, 195, 360, 360, 360, 379,
- 360, 360, 200, 360, 375, 376, 377, 381,
- 84, 79, 194, 195, 360, 360, 113, 379,
- 360, 360, 200, 360, 373, 360, 427, 360,
- 410, 410, 84, 79, 194, 195, 360, 360,
- 360, 365, 360, 373, 360, 373, 360, 360,
- 360, 401, 401, 360, 79, 194, 195, 360,
- 360, 360, 365, 360, 373, 360, 373, 360,
- 360, 360, 401, 428, 360, 79, 194, 195,
- 360, 360, 360, 365, 360, 373, 360, 373,
- 360, 427, 360, 401, 401, 360, 79, 194,
- 195, 360, 360, 360, 365, 360, 373, 360,
- 373, 81, 360, 360, 98, 374, 360, 79,
- 194, 195, 360, 360, 360, 365, 360, 373,
- 360, 366, 367, 372, 372, 84, 79, 194,
- 195, 360, 360, 360, 370, 360, 360, 200,
- 360, 366, 367, 368, 372, 84, 79, 194,
- 195, 360, 360, 115, 370, 360, 360, 200,
- 360, 363, 360, 429, 360, 410, 410, 84,
- 79, 194, 195, 360, 360, 360, 365, 360,
- 363, 360, 363, 360, 360, 360, 401, 401,
- 360, 79, 194, 195, 360, 360, 360, 365,
- 360, 363, 360, 363, 360, 360, 360, 401,
- 430, 360, 79, 194, 195, 360, 360, 360,
- 365, 360, 363, 360, 363, 360, 429, 360,
- 401, 401, 360, 79, 194, 195, 360, 360,
- 360, 365, 360, 363, 360, 363, 81, 360,
- 360, 98, 364, 360, 79, 194, 195, 360,
- 360, 360, 365, 360, 363, 360, 116, 83,
- 83, 84, 79, 431, 431, 431, 431, 156,
- 116, 431, 190, 191, 362, 362, 84, 79,
- 194, 195, 360, 360, 360, 197, 360, 360,
- 200, 360, 116, 83, 83, 84, 79, 431,
- 431, 431, 431, 431, 116, 431, 433, 434,
- 435, 436, 123, 118, 437, 438, 432, 432,
- 155, 439, 432, 432, 440, 432, 441, 434,
- 436, 436, 123, 118, 437, 438, 432, 432,
- 432, 439, 432, 432, 440, 432, 434, 436,
- 436, 123, 118, 437, 438, 432, 432, 432,
- 439, 432, 432, 440, 432, 442, 432, 432,
- 432, 136, 443, 432, 118, 437, 438, 432,
- 432, 432, 444, 432, 442, 432, 445, 446,
- 447, 448, 123, 118, 437, 438, 432, 432,
- 153, 449, 432, 432, 440, 432, 450, 446,
- 451, 451, 123, 118, 437, 438, 432, 432,
- 432, 449, 432, 432, 440, 432, 446, 451,
- 451, 123, 118, 437, 438, 432, 432, 432,
- 449, 432, 432, 440, 432, 452, 432, 432,
- 432, 136, 453, 432, 118, 437, 438, 432,
- 432, 432, 444, 432, 452, 432, 454, 455,
- 456, 457, 123, 118, 437, 438, 432, 432,
- 151, 458, 432, 432, 440, 432, 459, 455,
- 460, 460, 123, 118, 437, 438, 432, 432,
- 432, 458, 432, 432, 440, 432, 455, 460,
- 460, 123, 118, 437, 438, 432, 432, 432,
- 458, 432, 432, 440, 432, 461, 432, 432,
- 432, 136, 462, 432, 118, 437, 438, 432,
- 432, 432, 444, 432, 461, 432, 463, 464,
- 465, 466, 123, 118, 437, 438, 432, 432,
- 149, 467, 432, 432, 440, 432, 468, 464,
- 469, 469, 123, 118, 437, 438, 432, 432,
- 432, 467, 432, 432, 440, 432, 464, 469,
- 469, 123, 118, 437, 438, 432, 432, 432,
- 467, 432, 432, 440, 432, 470, 432, 432,
- 432, 136, 471, 432, 118, 437, 438, 432,
- 432, 432, 444, 432, 470, 432, 472, 473,
- 474, 475, 123, 118, 437, 438, 432, 432,
- 147, 476, 432, 432, 440, 432, 477, 473,
- 478, 478, 123, 118, 437, 438, 432, 432,
- 432, 476, 432, 432, 440, 432, 473, 478,
- 478, 123, 118, 437, 438, 432, 432, 432,
- 476, 432, 432, 440, 432, 136, 479, 432,
- 118, 437, 438, 432, 432, 432, 444, 432,
- 480, 480, 432, 118, 437, 438, 432, 432,
- 432, 444, 432, 481, 432, 432, 482, 437,
- 438, 432, 437, 438, 432, 483, 432, 437,
- 484, 432, 437, 485, 432, 437, 432, 481,
- 432, 432, 432, 437, 438, 432, 486, 432,
- 487, 488, 432, 118, 437, 438, 432, 432,
- 121, 432, 120, 432, 480, 480, 432, 118,
- 437, 438, 432, 480, 480, 432, 118, 437,
- 438, 432, 486, 432, 480, 480, 432, 118,
- 437, 438, 432, 486, 432, 487, 480, 432,
- 118, 437, 438, 432, 432, 121, 432, 136,
- 432, 489, 489, 123, 118, 437, 438, 432,
- 432, 432, 444, 432, 490, 145, 491, 492,
- 126, 118, 437, 438, 432, 432, 432, 444,
- 432, 145, 491, 492, 126, 118, 437, 438,
- 432, 432, 432, 444, 432, 491, 491, 126,
- 118, 437, 438, 432, 432, 432, 444, 432,
- 493, 142, 494, 495, 129, 118, 437, 438,
- 432, 432, 432, 444, 432, 142, 494, 495,
- 129, 118, 437, 438, 432, 432, 432, 444,
- 432, 494, 494, 129, 118, 437, 438, 432,
- 432, 432, 444, 432, 496, 139, 497, 498,
- 132, 118, 437, 438, 432, 432, 432, 444,
- 432, 139, 497, 498, 132, 118, 437, 438,
- 432, 432, 432, 444, 432, 497, 497, 132,
- 118, 437, 438, 432, 432, 432, 444, 432,
- 499, 136, 480, 500, 432, 118, 437, 438,
- 432, 432, 432, 444, 432, 136, 480, 500,
- 432, 118, 437, 438, 432, 432, 432, 444,
- 432, 480, 501, 432, 118, 437, 438, 432,
- 432, 432, 444, 432, 136, 432, 480, 480,
- 432, 118, 437, 438, 432, 432, 432, 444,
- 432, 119, 120, 432, 432, 136, 479, 432,
- 118, 437, 438, 432, 432, 432, 444, 432,
- 119, 432, 473, 478, 478, 123, 118, 437,
- 438, 432, 432, 432, 476, 432, 472, 473,
- 478, 478, 123, 118, 437, 438, 432, 432,
- 432, 476, 432, 432, 440, 432, 472, 473,
- 474, 478, 123, 118, 437, 438, 432, 432,
- 147, 476, 432, 432, 440, 432, 470, 432,
- 502, 432, 489, 489, 123, 118, 437, 438,
- 432, 432, 432, 444, 432, 470, 432, 470,
- 432, 432, 432, 480, 480, 432, 118, 437,
- 438, 432, 432, 432, 444, 432, 470, 432,
- 470, 432, 432, 432, 480, 503, 432, 118,
- 437, 438, 432, 432, 432, 444, 432, 470,
- 432, 470, 432, 502, 432, 480, 480, 432,
- 118, 437, 438, 432, 432, 432, 444, 432,
- 470, 432, 470, 120, 432, 432, 136, 471,
- 432, 118, 437, 438, 432, 432, 432, 444,
- 432, 470, 432, 463, 464, 469, 469, 123,
- 118, 437, 438, 432, 432, 432, 467, 432,
- 432, 440, 432, 463, 464, 465, 469, 123,
- 118, 437, 438, 432, 432, 149, 467, 432,
- 432, 440, 432, 461, 432, 504, 432, 489,
- 489, 123, 118, 437, 438, 432, 432, 432,
- 444, 432, 461, 432, 461, 432, 432, 432,
- 480, 480, 432, 118, 437, 438, 432, 432,
- 432, 444, 432, 461, 432, 461, 432, 432,
- 432, 480, 505, 432, 118, 437, 438, 432,
- 432, 432, 444, 432, 461, 432, 461, 432,
- 504, 432, 480, 480, 432, 118, 437, 438,
- 432, 432, 432, 444, 432, 461, 432, 461,
- 120, 432, 432, 136, 462, 432, 118, 437,
- 438, 432, 432, 432, 444, 432, 461, 432,
- 454, 455, 460, 460, 123, 118, 437, 438,
- 432, 432, 432, 458, 432, 432, 440, 432,
- 454, 455, 456, 460, 123, 118, 437, 438,
- 432, 432, 151, 458, 432, 432, 440, 432,
- 452, 432, 506, 432, 489, 489, 123, 118,
- 437, 438, 432, 432, 432, 444, 432, 452,
- 432, 452, 432, 432, 432, 480, 480, 432,
- 118, 437, 438, 432, 432, 432, 444, 432,
- 452, 432, 452, 432, 432, 432, 480, 507,
- 432, 118, 437, 438, 432, 432, 432, 444,
- 432, 452, 432, 452, 432, 506, 432, 480,
- 480, 432, 118, 437, 438, 432, 432, 432,
- 444, 432, 452, 432, 452, 120, 432, 432,
- 136, 453, 432, 118, 437, 438, 432, 432,
- 432, 444, 432, 452, 432, 445, 446, 451,
- 451, 123, 118, 437, 438, 432, 432, 432,
- 449, 432, 432, 440, 432, 445, 446, 447,
- 451, 123, 118, 437, 438, 432, 432, 153,
- 449, 432, 432, 440, 432, 442, 432, 508,
- 432, 489, 489, 123, 118, 437, 438, 432,
- 432, 432, 444, 432, 442, 432, 442, 432,
- 432, 432, 480, 480, 432, 118, 437, 438,
- 432, 432, 432, 444, 432, 442, 432, 442,
- 432, 432, 432, 480, 509, 432, 118, 437,
- 438, 432, 432, 432, 444, 432, 442, 432,
- 442, 432, 508, 432, 480, 480, 432, 118,
- 437, 438, 432, 432, 432, 444, 432, 442,
- 432, 442, 120, 432, 432, 136, 443, 432,
- 118, 437, 438, 432, 432, 432, 444, 432,
- 442, 432, 433, 434, 436, 436, 123, 118,
- 437, 438, 432, 432, 432, 439, 432, 432,
- 440, 432, 188, 189, 190, 191, 510, 362,
- 84, 79, 194, 195, 196, 196, 156, 197,
- 360, 188, 200, 360, 203, 511, 205, 206,
- 6, 1, 207, 208, 202, 202, 38, 209,
- 202, 202, 210, 202, 213, 189, 190, 191,
- 512, 513, 84, 157, 514, 515, 202, 196,
- 156, 516, 202, 213, 200, 202, 116, 517,
- 517, 84, 157, 207, 208, 202, 202, 156,
- 518, 202, 519, 202, 202, 520, 514, 515,
- 202, 514, 515, 202, 254, 202, 514, 521,
- 202, 514, 522, 202, 514, 202, 519, 202,
- 202, 202, 514, 515, 202, 523, 3, 360,
- 360, 401, 430, 360, 79, 194, 195, 360,
- 360, 360, 365, 360, 523, 360, 524, 367,
- 525, 526, 84, 157, 514, 515, 202, 202,
- 158, 370, 202, 202, 200, 202, 527, 367,
- 528, 528, 84, 157, 514, 515, 202, 202,
- 202, 370, 202, 202, 200, 202, 367, 528,
- 528, 84, 157, 514, 515, 202, 202, 202,
- 370, 202, 202, 200, 202, 524, 367, 528,
- 528, 84, 157, 514, 515, 202, 202, 202,
- 370, 202, 202, 200, 202, 524, 367, 525,
- 528, 84, 157, 514, 515, 202, 202, 158,
- 370, 202, 202, 200, 202, 213, 202, 279,
- 116, 529, 529, 160, 157, 207, 208, 202,
- 202, 202, 518, 202, 213, 202, 530, 184,
- 531, 532, 162, 157, 514, 515, 202, 202,
- 202, 533, 202, 184, 531, 532, 162, 157,
- 514, 515, 202, 202, 202, 533, 202, 531,
- 531, 162, 157, 514, 515, 202, 202, 202,
- 533, 202, 534, 181, 535, 536, 165, 157,
- 514, 515, 202, 202, 202, 533, 202, 181,
- 535, 536, 165, 157, 514, 515, 202, 202,
- 202, 533, 202, 535, 535, 165, 157, 514,
- 515, 202, 202, 202, 533, 202, 537, 178,
- 538, 539, 168, 157, 514, 515, 202, 202,
- 202, 533, 202, 178, 538, 539, 168, 157,
- 514, 515, 202, 202, 202, 533, 202, 538,
- 538, 168, 157, 514, 515, 202, 202, 202,
- 533, 202, 540, 175, 541, 542, 202, 157,
- 514, 515, 202, 202, 202, 533, 202, 175,
- 541, 542, 202, 157, 514, 515, 202, 202,
- 202, 533, 202, 541, 541, 202, 157, 514,
- 515, 202, 202, 202, 533, 202, 543, 202,
- 544, 545, 202, 157, 514, 515, 202, 202,
- 172, 202, 171, 202, 541, 541, 202, 157,
- 514, 515, 202, 541, 541, 202, 157, 514,
- 515, 202, 543, 202, 541, 541, 202, 157,
- 514, 515, 202, 543, 202, 544, 541, 202,
- 157, 514, 515, 202, 202, 172, 202, 523,
- 171, 360, 360, 98, 364, 360, 79, 194,
- 195, 360, 360, 360, 365, 360, 523, 360,
- 547, 546, 548, 548, 546, 186, 549, 550,
- 546, 548, 548, 546, 186, 549, 550, 546,
- 551, 546, 546, 552, 549, 550, 546, 549,
- 550, 546, 553, 546, 549, 554, 546, 549,
- 555, 546, 549, 546, 551, 546, 546, 546,
- 549, 550, 546, 0
+ 197, 198, 199, 200, 201, 202, 187, 204,
+ 205, 206, 207, 6, 1, 208, 209, 203,
+ 203, 38, 210, 203, 203, 211, 203, 212,
+ 205, 213, 213, 6, 1, 208, 209, 203,
+ 203, 203, 210, 203, 203, 211, 203, 205,
+ 213, 213, 6, 1, 208, 209, 203, 203,
+ 203, 210, 203, 203, 211, 203, 214, 203,
+ 203, 203, 19, 215, 203, 1, 208, 209,
+ 203, 203, 203, 216, 203, 214, 203, 217,
+ 218, 219, 220, 6, 1, 208, 209, 203,
+ 203, 36, 221, 203, 203, 211, 203, 222,
+ 218, 223, 223, 6, 1, 208, 209, 203,
+ 203, 203, 221, 203, 203, 211, 203, 218,
+ 223, 223, 6, 1, 208, 209, 203, 203,
+ 203, 221, 203, 203, 211, 203, 224, 203,
+ 203, 203, 19, 225, 203, 1, 208, 209,
+ 203, 203, 203, 216, 203, 224, 203, 226,
+ 227, 228, 229, 6, 1, 208, 209, 203,
+ 203, 34, 230, 203, 203, 211, 203, 231,
+ 227, 232, 232, 6, 1, 208, 209, 203,
+ 203, 203, 230, 203, 203, 211, 203, 227,
+ 232, 232, 6, 1, 208, 209, 203, 203,
+ 203, 230, 203, 203, 211, 203, 233, 203,
+ 203, 203, 19, 234, 203, 1, 208, 209,
+ 203, 203, 203, 216, 203, 233, 203, 235,
+ 236, 237, 238, 6, 1, 208, 209, 203,
+ 203, 32, 239, 203, 203, 211, 203, 240,
+ 236, 241, 241, 6, 1, 208, 209, 203,
+ 203, 203, 239, 203, 203, 211, 203, 236,
+ 241, 241, 6, 1, 208, 209, 203, 203,
+ 203, 239, 203, 203, 211, 203, 242, 203,
+ 203, 203, 19, 243, 203, 1, 208, 209,
+ 203, 203, 203, 216, 203, 242, 203, 244,
+ 245, 246, 247, 6, 1, 208, 209, 203,
+ 203, 30, 248, 203, 203, 211, 203, 249,
+ 245, 250, 250, 6, 1, 208, 209, 203,
+ 203, 203, 248, 203, 203, 211, 203, 245,
+ 250, 250, 6, 1, 208, 209, 203, 203,
+ 203, 248, 203, 203, 211, 203, 19, 251,
+ 203, 1, 208, 209, 203, 203, 203, 216,
+ 203, 252, 252, 203, 1, 208, 209, 203,
+ 203, 203, 216, 203, 253, 203, 203, 254,
+ 208, 209, 203, 208, 209, 203, 255, 203,
+ 208, 256, 203, 208, 257, 203, 208, 203,
+ 253, 203, 203, 203, 208, 209, 203, 258,
+ 203, 259, 260, 203, 1, 208, 209, 203,
+ 203, 4, 203, 3, 203, 252, 252, 203,
+ 1, 208, 209, 203, 252, 252, 203, 1,
+ 208, 209, 203, 258, 203, 252, 252, 203,
+ 1, 208, 209, 203, 258, 203, 259, 252,
+ 203, 1, 208, 209, 203, 203, 4, 203,
+ 19, 203, 261, 261, 6, 1, 208, 209,
+ 203, 203, 203, 216, 203, 262, 28, 263,
+ 264, 9, 1, 208, 209, 203, 203, 203,
+ 216, 203, 28, 263, 264, 9, 1, 208,
+ 209, 203, 203, 203, 216, 203, 263, 263,
+ 9, 1, 208, 209, 203, 203, 203, 216,
+ 203, 265, 25, 266, 267, 12, 1, 208,
+ 209, 203, 203, 203, 216, 203, 25, 266,
+ 267, 12, 1, 208, 209, 203, 203, 203,
+ 216, 203, 266, 266, 12, 1, 208, 209,
+ 203, 203, 203, 216, 203, 268, 22, 269,
+ 270, 15, 1, 208, 209, 203, 203, 203,
+ 216, 203, 22, 269, 270, 15, 1, 208,
+ 209, 203, 203, 203, 216, 203, 269, 269,
+ 15, 1, 208, 209, 203, 203, 203, 216,
+ 203, 271, 19, 252, 272, 203, 1, 208,
+ 209, 203, 203, 203, 216, 203, 19, 252,
+ 272, 203, 1, 208, 209, 203, 203, 203,
+ 216, 203, 252, 273, 203, 1, 208, 209,
+ 203, 203, 203, 216, 203, 19, 203, 252,
+ 252, 203, 1, 208, 209, 203, 203, 203,
+ 216, 203, 2, 3, 203, 203, 19, 251,
+ 203, 1, 208, 209, 203, 203, 203, 216,
+ 203, 2, 203, 245, 250, 250, 6, 1,
+ 208, 209, 203, 203, 203, 248, 203, 244,
+ 245, 250, 250, 6, 1, 208, 209, 203,
+ 203, 203, 248, 203, 203, 211, 203, 244,
+ 245, 246, 250, 6, 1, 208, 209, 203,
+ 203, 30, 248, 203, 203, 211, 203, 242,
+ 203, 274, 203, 261, 261, 6, 1, 208,
+ 209, 203, 203, 203, 216, 203, 242, 203,
+ 242, 203, 203, 203, 252, 252, 203, 1,
+ 208, 209, 203, 203, 203, 216, 203, 242,
+ 203, 242, 203, 203, 203, 252, 275, 203,
+ 1, 208, 209, 203, 203, 203, 216, 203,
+ 242, 203, 242, 203, 274, 203, 252, 252,
+ 203, 1, 208, 209, 203, 203, 203, 216,
+ 203, 242, 203, 242, 3, 203, 203, 19,
+ 243, 203, 1, 208, 209, 203, 203, 203,
+ 216, 203, 242, 203, 235, 236, 241, 241,
+ 6, 1, 208, 209, 203, 203, 203, 239,
+ 203, 203, 211, 203, 235, 236, 237, 241,
+ 6, 1, 208, 209, 203, 203, 32, 239,
+ 203, 203, 211, 203, 233, 203, 276, 203,
+ 261, 261, 6, 1, 208, 209, 203, 203,
+ 203, 216, 203, 233, 203, 233, 203, 203,
+ 203, 252, 252, 203, 1, 208, 209, 203,
+ 203, 203, 216, 203, 233, 203, 233, 203,
+ 203, 203, 252, 277, 203, 1, 208, 209,
+ 203, 203, 203, 216, 203, 233, 203, 233,
+ 203, 276, 203, 252, 252, 203, 1, 208,
+ 209, 203, 203, 203, 216, 203, 233, 203,
+ 233, 3, 203, 203, 19, 234, 203, 1,
+ 208, 209, 203, 203, 203, 216, 203, 233,
+ 203, 226, 227, 232, 232, 6, 1, 208,
+ 209, 203, 203, 203, 230, 203, 203, 211,
+ 203, 226, 227, 228, 232, 6, 1, 208,
+ 209, 203, 203, 34, 230, 203, 203, 211,
+ 203, 224, 203, 278, 203, 261, 261, 6,
+ 1, 208, 209, 203, 203, 203, 216, 203,
+ 224, 203, 224, 203, 203, 203, 252, 252,
+ 203, 1, 208, 209, 203, 203, 203, 216,
+ 203, 224, 203, 224, 203, 203, 203, 252,
+ 279, 203, 1, 208, 209, 203, 203, 203,
+ 216, 203, 224, 203, 224, 203, 278, 203,
+ 252, 252, 203, 1, 208, 209, 203, 203,
+ 203, 216, 203, 224, 203, 224, 3, 203,
+ 203, 19, 225, 203, 1, 208, 209, 203,
+ 203, 203, 216, 203, 224, 203, 217, 218,
+ 223, 223, 6, 1, 208, 209, 203, 203,
+ 203, 221, 203, 203, 211, 203, 217, 218,
+ 219, 223, 6, 1, 208, 209, 203, 203,
+ 36, 221, 203, 203, 211, 203, 214, 203,
+ 280, 203, 261, 261, 6, 1, 208, 209,
+ 203, 203, 203, 216, 203, 214, 203, 214,
+ 203, 203, 203, 252, 252, 203, 1, 208,
+ 209, 203, 203, 203, 216, 203, 214, 203,
+ 214, 203, 203, 203, 252, 281, 203, 1,
+ 208, 209, 203, 203, 203, 216, 203, 214,
+ 203, 214, 203, 280, 203, 252, 252, 203,
+ 1, 208, 209, 203, 203, 203, 216, 203,
+ 214, 203, 214, 3, 203, 203, 19, 215,
+ 203, 1, 208, 209, 203, 203, 203, 216,
+ 203, 214, 203, 204, 205, 213, 213, 6,
+ 1, 208, 209, 203, 203, 203, 210, 203,
+ 203, 211, 203, 204, 205, 206, 213, 6,
+ 1, 208, 209, 203, 203, 38, 210, 203,
+ 203, 211, 203, 283, 284, 285, 286, 45,
+ 40, 287, 288, 282, 282, 77, 289, 282,
+ 282, 290, 282, 291, 284, 292, 286, 45,
+ 40, 287, 288, 282, 282, 282, 289, 282,
+ 282, 290, 282, 284, 292, 286, 45, 40,
+ 287, 288, 282, 282, 282, 289, 282, 282,
+ 290, 282, 293, 282, 282, 282, 58, 294,
+ 282, 40, 287, 288, 282, 282, 282, 295,
+ 282, 293, 282, 296, 297, 298, 299, 45,
+ 40, 287, 288, 282, 282, 75, 300, 282,
+ 282, 290, 282, 301, 297, 302, 302, 45,
+ 40, 287, 288, 282, 282, 282, 300, 282,
+ 282, 290, 282, 297, 302, 302, 45, 40,
+ 287, 288, 282, 282, 282, 300, 282, 282,
+ 290, 282, 303, 282, 282, 282, 58, 304,
+ 282, 40, 287, 288, 282, 282, 282, 295,
+ 282, 303, 282, 305, 306, 307, 308, 45,
+ 40, 287, 288, 282, 282, 73, 309, 282,
+ 282, 290, 282, 310, 306, 311, 311, 45,
+ 40, 287, 288, 282, 282, 282, 309, 282,
+ 282, 290, 282, 306, 311, 311, 45, 40,
+ 287, 288, 282, 282, 282, 309, 282, 282,
+ 290, 282, 312, 282, 282, 282, 58, 313,
+ 282, 40, 287, 288, 282, 282, 282, 295,
+ 282, 312, 282, 314, 315, 316, 317, 45,
+ 40, 287, 288, 282, 282, 71, 318, 282,
+ 282, 290, 282, 319, 315, 320, 320, 45,
+ 40, 287, 288, 282, 282, 282, 318, 282,
+ 282, 290, 282, 315, 320, 320, 45, 40,
+ 287, 288, 282, 282, 282, 318, 282, 282,
+ 290, 282, 321, 282, 282, 282, 58, 322,
+ 282, 40, 287, 288, 282, 282, 282, 295,
+ 282, 321, 282, 323, 324, 325, 326, 45,
+ 40, 287, 288, 282, 282, 69, 327, 282,
+ 282, 290, 282, 328, 324, 329, 329, 45,
+ 40, 287, 288, 282, 282, 282, 327, 282,
+ 282, 290, 282, 324, 329, 329, 45, 40,
+ 287, 288, 282, 282, 282, 327, 282, 282,
+ 290, 282, 58, 330, 282, 40, 287, 288,
+ 282, 282, 282, 295, 282, 331, 331, 282,
+ 40, 287, 288, 282, 282, 282, 295, 282,
+ 332, 282, 282, 333, 287, 288, 282, 287,
+ 288, 282, 334, 282, 287, 335, 282, 287,
+ 336, 282, 287, 282, 332, 282, 282, 282,
+ 287, 288, 282, 337, 282, 338, 339, 282,
+ 40, 287, 288, 282, 282, 43, 282, 42,
+ 282, 331, 331, 282, 40, 287, 288, 282,
+ 331, 331, 282, 40, 287, 288, 282, 337,
+ 282, 331, 331, 282, 40, 287, 288, 282,
+ 337, 282, 338, 331, 282, 40, 287, 288,
+ 282, 282, 43, 282, 58, 282, 340, 340,
+ 45, 40, 287, 288, 282, 282, 282, 295,
+ 282, 341, 67, 342, 343, 48, 40, 287,
+ 288, 282, 282, 282, 295, 282, 67, 342,
+ 343, 48, 40, 287, 288, 282, 282, 282,
+ 295, 282, 342, 342, 48, 40, 287, 288,
+ 282, 282, 282, 295, 282, 344, 64, 345,
+ 346, 51, 40, 287, 288, 282, 282, 282,
+ 295, 282, 64, 345, 346, 51, 40, 287,
+ 288, 282, 282, 282, 295, 282, 345, 345,
+ 51, 40, 287, 288, 282, 282, 282, 295,
+ 282, 347, 61, 348, 349, 54, 40, 287,
+ 288, 282, 282, 282, 295, 282, 61, 348,
+ 349, 54, 40, 287, 288, 282, 282, 282,
+ 295, 282, 348, 348, 54, 40, 287, 288,
+ 282, 282, 282, 295, 282, 350, 58, 331,
+ 351, 282, 40, 287, 288, 282, 282, 282,
+ 295, 282, 58, 331, 351, 282, 40, 287,
+ 288, 282, 282, 282, 295, 282, 331, 352,
+ 282, 40, 287, 288, 282, 282, 282, 295,
+ 282, 58, 282, 331, 331, 282, 40, 287,
+ 288, 282, 282, 282, 295, 282, 41, 42,
+ 282, 282, 58, 330, 282, 40, 287, 288,
+ 282, 282, 282, 295, 282, 41, 282, 324,
+ 329, 329, 45, 40, 287, 288, 282, 282,
+ 282, 327, 282, 323, 324, 329, 329, 45,
+ 40, 287, 288, 282, 282, 282, 327, 282,
+ 282, 290, 282, 323, 324, 325, 329, 45,
+ 40, 287, 288, 282, 282, 69, 327, 282,
+ 282, 290, 282, 321, 282, 353, 282, 340,
+ 340, 45, 40, 287, 288, 282, 282, 282,
+ 295, 282, 321, 282, 321, 282, 282, 282,
+ 331, 331, 282, 40, 287, 288, 282, 282,
+ 282, 295, 282, 321, 282, 321, 282, 282,
+ 282, 331, 354, 282, 40, 287, 288, 282,
+ 282, 282, 295, 282, 321, 282, 321, 282,
+ 353, 282, 331, 331, 282, 40, 287, 288,
+ 282, 282, 282, 295, 282, 321, 282, 321,
+ 42, 282, 282, 58, 322, 282, 40, 287,
+ 288, 282, 282, 282, 295, 282, 321, 282,
+ 314, 315, 320, 320, 45, 40, 287, 288,
+ 282, 282, 282, 318, 282, 282, 290, 282,
+ 314, 315, 316, 320, 45, 40, 287, 288,
+ 282, 282, 71, 318, 282, 282, 290, 282,
+ 312, 282, 355, 282, 340, 340, 45, 40,
+ 287, 288, 282, 282, 282, 295, 282, 312,
+ 282, 312, 282, 282, 282, 331, 331, 282,
+ 40, 287, 288, 282, 282, 282, 295, 282,
+ 312, 282, 312, 282, 282, 282, 331, 356,
+ 282, 40, 287, 288, 282, 282, 282, 295,
+ 282, 312, 282, 312, 282, 355, 282, 331,
+ 331, 282, 40, 287, 288, 282, 282, 282,
+ 295, 282, 312, 282, 312, 42, 282, 282,
+ 58, 313, 282, 40, 287, 288, 282, 282,
+ 282, 295, 282, 312, 282, 305, 306, 311,
+ 311, 45, 40, 287, 288, 282, 282, 282,
+ 309, 282, 282, 290, 282, 305, 306, 307,
+ 311, 45, 40, 287, 288, 282, 282, 73,
+ 309, 282, 282, 290, 282, 303, 282, 357,
+ 282, 340, 340, 45, 40, 287, 288, 282,
+ 282, 282, 295, 282, 303, 282, 303, 282,
+ 282, 282, 331, 331, 282, 40, 287, 288,
+ 282, 282, 282, 295, 282, 303, 282, 303,
+ 282, 282, 282, 331, 358, 282, 40, 287,
+ 288, 282, 282, 282, 295, 282, 303, 282,
+ 303, 282, 357, 282, 331, 331, 282, 40,
+ 287, 288, 282, 282, 282, 295, 282, 303,
+ 282, 303, 42, 282, 282, 58, 304, 282,
+ 40, 287, 288, 282, 282, 282, 295, 282,
+ 303, 282, 296, 297, 302, 302, 45, 40,
+ 287, 288, 282, 282, 282, 300, 282, 282,
+ 290, 282, 296, 297, 298, 302, 45, 40,
+ 287, 288, 282, 282, 75, 300, 282, 282,
+ 290, 282, 293, 282, 359, 282, 340, 340,
+ 45, 40, 287, 288, 282, 282, 282, 295,
+ 282, 293, 282, 293, 282, 282, 282, 331,
+ 331, 282, 40, 287, 288, 282, 282, 282,
+ 295, 282, 293, 282, 293, 282, 282, 282,
+ 331, 360, 282, 40, 287, 288, 282, 282,
+ 282, 295, 282, 293, 282, 293, 282, 359,
+ 282, 331, 331, 282, 40, 287, 288, 282,
+ 282, 282, 295, 282, 293, 282, 76, 44,
+ 44, 45, 40, 282, 282, 282, 282, 282,
+ 76, 282, 293, 42, 282, 282, 58, 294,
+ 282, 40, 287, 288, 282, 282, 282, 295,
+ 282, 293, 282, 283, 284, 292, 286, 45,
+ 40, 287, 288, 282, 282, 282, 289, 282,
+ 282, 290, 282, 362, 191, 363, 363, 84,
+ 79, 194, 195, 361, 361, 361, 197, 361,
+ 361, 200, 361, 191, 363, 363, 84, 79,
+ 194, 195, 361, 361, 361, 197, 361, 361,
+ 200, 361, 364, 361, 361, 361, 98, 365,
+ 361, 79, 194, 195, 361, 361, 361, 366,
+ 361, 364, 361, 367, 368, 369, 370, 84,
+ 79, 194, 195, 361, 361, 115, 371, 361,
+ 361, 200, 361, 372, 368, 373, 373, 84,
+ 79, 194, 195, 361, 361, 361, 371, 361,
+ 361, 200, 361, 368, 373, 373, 84, 79,
+ 194, 195, 361, 361, 361, 371, 361, 361,
+ 200, 361, 374, 361, 361, 361, 98, 375,
+ 361, 79, 194, 195, 361, 361, 361, 366,
+ 361, 374, 361, 376, 377, 378, 379, 84,
+ 79, 194, 195, 361, 361, 113, 380, 361,
+ 361, 200, 361, 381, 377, 382, 382, 84,
+ 79, 194, 195, 361, 361, 361, 380, 361,
+ 361, 200, 361, 377, 382, 382, 84, 79,
+ 194, 195, 361, 361, 361, 380, 361, 361,
+ 200, 361, 383, 361, 361, 361, 98, 384,
+ 361, 79, 194, 195, 361, 361, 361, 366,
+ 361, 383, 361, 385, 386, 387, 388, 84,
+ 79, 194, 195, 361, 361, 111, 389, 361,
+ 361, 200, 361, 390, 386, 391, 391, 84,
+ 79, 194, 195, 361, 361, 361, 389, 361,
+ 361, 200, 361, 386, 391, 391, 84, 79,
+ 194, 195, 361, 361, 361, 389, 361, 361,
+ 200, 361, 392, 361, 361, 361, 98, 393,
+ 361, 79, 194, 195, 361, 361, 361, 366,
+ 361, 392, 361, 394, 395, 396, 397, 84,
+ 79, 194, 195, 361, 361, 109, 398, 361,
+ 361, 200, 361, 399, 395, 400, 400, 84,
+ 79, 194, 195, 361, 361, 361, 398, 361,
+ 361, 200, 361, 395, 400, 400, 84, 79,
+ 194, 195, 361, 361, 361, 398, 361, 361,
+ 200, 361, 98, 401, 361, 79, 194, 195,
+ 361, 361, 361, 366, 361, 402, 402, 361,
+ 79, 194, 195, 361, 361, 361, 366, 361,
+ 403, 361, 361, 404, 194, 195, 361, 194,
+ 195, 361, 405, 361, 194, 406, 361, 194,
+ 407, 361, 194, 361, 403, 361, 361, 361,
+ 194, 195, 361, 408, 361, 409, 410, 361,
+ 79, 194, 195, 361, 361, 82, 361, 81,
+ 361, 402, 402, 361, 79, 194, 195, 361,
+ 402, 402, 361, 79, 194, 195, 361, 408,
+ 361, 402, 402, 361, 79, 194, 195, 361,
+ 408, 361, 409, 402, 361, 79, 194, 195,
+ 361, 361, 82, 361, 98, 361, 411, 411,
+ 84, 79, 194, 195, 361, 361, 361, 366,
+ 361, 412, 107, 413, 414, 88, 79, 194,
+ 195, 361, 361, 361, 366, 361, 107, 413,
+ 414, 88, 79, 194, 195, 361, 361, 361,
+ 366, 361, 413, 413, 88, 79, 194, 195,
+ 361, 361, 361, 366, 361, 415, 104, 416,
+ 417, 91, 79, 194, 195, 361, 361, 361,
+ 366, 361, 104, 416, 417, 91, 79, 194,
+ 195, 361, 361, 361, 366, 361, 416, 416,
+ 91, 79, 194, 195, 361, 361, 361, 366,
+ 361, 418, 101, 419, 420, 94, 79, 194,
+ 195, 361, 361, 361, 366, 361, 101, 419,
+ 420, 94, 79, 194, 195, 361, 361, 361,
+ 366, 361, 419, 419, 94, 79, 194, 195,
+ 361, 361, 361, 366, 361, 421, 98, 402,
+ 422, 361, 79, 194, 195, 361, 361, 361,
+ 366, 361, 98, 402, 422, 361, 79, 194,
+ 195, 361, 361, 361, 366, 361, 402, 423,
+ 361, 79, 194, 195, 361, 361, 361, 366,
+ 361, 98, 361, 402, 402, 361, 79, 194,
+ 195, 361, 361, 361, 366, 361, 80, 81,
+ 361, 361, 98, 401, 361, 79, 194, 195,
+ 361, 361, 361, 366, 361, 80, 361, 395,
+ 400, 400, 84, 79, 194, 195, 361, 361,
+ 361, 398, 361, 394, 395, 400, 400, 84,
+ 79, 194, 195, 361, 361, 361, 398, 361,
+ 361, 200, 361, 394, 395, 396, 400, 84,
+ 79, 194, 195, 361, 361, 109, 398, 361,
+ 361, 200, 361, 392, 361, 424, 361, 411,
+ 411, 84, 79, 194, 195, 361, 361, 361,
+ 366, 361, 392, 361, 392, 361, 361, 361,
+ 402, 402, 361, 79, 194, 195, 361, 361,
+ 361, 366, 361, 392, 361, 392, 361, 361,
+ 361, 402, 425, 361, 79, 194, 195, 361,
+ 361, 361, 366, 361, 392, 361, 392, 361,
+ 424, 361, 402, 402, 361, 79, 194, 195,
+ 361, 361, 361, 366, 361, 392, 361, 392,
+ 81, 361, 361, 98, 393, 361, 79, 194,
+ 195, 361, 361, 361, 366, 361, 392, 361,
+ 385, 386, 391, 391, 84, 79, 194, 195,
+ 361, 361, 361, 389, 361, 361, 200, 361,
+ 385, 386, 387, 391, 84, 79, 194, 195,
+ 361, 361, 111, 389, 361, 361, 200, 361,
+ 383, 361, 426, 361, 411, 411, 84, 79,
+ 194, 195, 361, 361, 361, 366, 361, 383,
+ 361, 383, 361, 361, 361, 402, 402, 361,
+ 79, 194, 195, 361, 361, 361, 366, 361,
+ 383, 361, 383, 361, 361, 361, 402, 427,
+ 361, 79, 194, 195, 361, 361, 361, 366,
+ 361, 383, 361, 383, 361, 426, 361, 402,
+ 402, 361, 79, 194, 195, 361, 361, 361,
+ 366, 361, 383, 361, 383, 81, 361, 361,
+ 98, 384, 361, 79, 194, 195, 361, 361,
+ 361, 366, 361, 383, 361, 376, 377, 382,
+ 382, 84, 79, 194, 195, 361, 361, 361,
+ 380, 361, 361, 200, 361, 376, 377, 378,
+ 382, 84, 79, 194, 195, 361, 361, 113,
+ 380, 361, 361, 200, 361, 374, 361, 428,
+ 361, 411, 411, 84, 79, 194, 195, 361,
+ 361, 361, 366, 361, 374, 361, 374, 361,
+ 361, 361, 402, 402, 361, 79, 194, 195,
+ 361, 361, 361, 366, 361, 374, 361, 374,
+ 361, 361, 361, 402, 429, 361, 79, 194,
+ 195, 361, 361, 361, 366, 361, 374, 361,
+ 374, 361, 428, 361, 402, 402, 361, 79,
+ 194, 195, 361, 361, 361, 366, 361, 374,
+ 361, 374, 81, 361, 361, 98, 375, 361,
+ 79, 194, 195, 361, 361, 361, 366, 361,
+ 374, 361, 367, 368, 373, 373, 84, 79,
+ 194, 195, 361, 361, 361, 371, 361, 361,
+ 200, 361, 367, 368, 369, 373, 84, 79,
+ 194, 195, 361, 361, 115, 371, 361, 361,
+ 200, 361, 364, 361, 430, 361, 411, 411,
+ 84, 79, 194, 195, 361, 361, 361, 366,
+ 361, 364, 361, 364, 361, 361, 361, 402,
+ 402, 361, 79, 194, 195, 361, 361, 361,
+ 366, 361, 364, 361, 364, 361, 361, 361,
+ 402, 431, 361, 79, 194, 195, 361, 361,
+ 361, 366, 361, 364, 361, 364, 361, 430,
+ 361, 402, 402, 361, 79, 194, 195, 361,
+ 361, 361, 366, 361, 364, 361, 364, 81,
+ 361, 361, 98, 365, 361, 79, 194, 195,
+ 361, 361, 361, 366, 361, 364, 361, 116,
+ 83, 83, 84, 79, 432, 432, 432, 432,
+ 156, 116, 432, 190, 191, 363, 363, 84,
+ 79, 194, 195, 361, 361, 361, 197, 361,
+ 361, 200, 361, 116, 83, 83, 84, 79,
+ 432, 432, 432, 432, 432, 116, 432, 434,
+ 435, 436, 437, 123, 118, 438, 439, 433,
+ 433, 155, 440, 433, 433, 441, 433, 442,
+ 435, 437, 437, 123, 118, 438, 439, 433,
+ 433, 433, 440, 433, 433, 441, 433, 435,
+ 437, 437, 123, 118, 438, 439, 433, 433,
+ 433, 440, 433, 433, 441, 433, 443, 433,
+ 433, 433, 136, 444, 433, 118, 438, 439,
+ 433, 433, 433, 445, 433, 443, 433, 446,
+ 447, 448, 449, 123, 118, 438, 439, 433,
+ 433, 153, 450, 433, 433, 441, 433, 451,
+ 447, 452, 452, 123, 118, 438, 439, 433,
+ 433, 433, 450, 433, 433, 441, 433, 447,
+ 452, 452, 123, 118, 438, 439, 433, 433,
+ 433, 450, 433, 433, 441, 433, 453, 433,
+ 433, 433, 136, 454, 433, 118, 438, 439,
+ 433, 433, 433, 445, 433, 453, 433, 455,
+ 456, 457, 458, 123, 118, 438, 439, 433,
+ 433, 151, 459, 433, 433, 441, 433, 460,
+ 456, 461, 461, 123, 118, 438, 439, 433,
+ 433, 433, 459, 433, 433, 441, 433, 456,
+ 461, 461, 123, 118, 438, 439, 433, 433,
+ 433, 459, 433, 433, 441, 433, 462, 433,
+ 433, 433, 136, 463, 433, 118, 438, 439,
+ 433, 433, 433, 445, 433, 462, 433, 464,
+ 465, 466, 467, 123, 118, 438, 439, 433,
+ 433, 149, 468, 433, 433, 441, 433, 469,
+ 465, 470, 470, 123, 118, 438, 439, 433,
+ 433, 433, 468, 433, 433, 441, 433, 465,
+ 470, 470, 123, 118, 438, 439, 433, 433,
+ 433, 468, 433, 433, 441, 433, 471, 433,
+ 433, 433, 136, 472, 433, 118, 438, 439,
+ 433, 433, 433, 445, 433, 471, 433, 473,
+ 474, 475, 476, 123, 118, 438, 439, 433,
+ 433, 147, 477, 433, 433, 441, 433, 478,
+ 474, 479, 479, 123, 118, 438, 439, 433,
+ 433, 433, 477, 433, 433, 441, 433, 474,
+ 479, 479, 123, 118, 438, 439, 433, 433,
+ 433, 477, 433, 433, 441, 433, 136, 480,
+ 433, 118, 438, 439, 433, 433, 433, 445,
+ 433, 481, 481, 433, 118, 438, 439, 433,
+ 433, 433, 445, 433, 482, 433, 433, 483,
+ 438, 439, 433, 438, 439, 433, 484, 433,
+ 438, 485, 433, 438, 486, 433, 438, 433,
+ 482, 433, 433, 433, 438, 439, 433, 487,
+ 433, 488, 489, 433, 118, 438, 439, 433,
+ 433, 121, 433, 120, 433, 481, 481, 433,
+ 118, 438, 439, 433, 481, 481, 433, 118,
+ 438, 439, 433, 487, 433, 481, 481, 433,
+ 118, 438, 439, 433, 487, 433, 488, 481,
+ 433, 118, 438, 439, 433, 433, 121, 433,
+ 136, 433, 490, 490, 123, 118, 438, 439,
+ 433, 433, 433, 445, 433, 491, 145, 492,
+ 493, 126, 118, 438, 439, 433, 433, 433,
+ 445, 433, 145, 492, 493, 126, 118, 438,
+ 439, 433, 433, 433, 445, 433, 492, 492,
+ 126, 118, 438, 439, 433, 433, 433, 445,
+ 433, 494, 142, 495, 496, 129, 118, 438,
+ 439, 433, 433, 433, 445, 433, 142, 495,
+ 496, 129, 118, 438, 439, 433, 433, 433,
+ 445, 433, 495, 495, 129, 118, 438, 439,
+ 433, 433, 433, 445, 433, 497, 139, 498,
+ 499, 132, 118, 438, 439, 433, 433, 433,
+ 445, 433, 139, 498, 499, 132, 118, 438,
+ 439, 433, 433, 433, 445, 433, 498, 498,
+ 132, 118, 438, 439, 433, 433, 433, 445,
+ 433, 500, 136, 481, 501, 433, 118, 438,
+ 439, 433, 433, 433, 445, 433, 136, 481,
+ 501, 433, 118, 438, 439, 433, 433, 433,
+ 445, 433, 481, 502, 433, 118, 438, 439,
+ 433, 433, 433, 445, 433, 136, 433, 481,
+ 481, 433, 118, 438, 439, 433, 433, 433,
+ 445, 433, 119, 120, 433, 433, 136, 480,
+ 433, 118, 438, 439, 433, 433, 433, 445,
+ 433, 119, 433, 474, 479, 479, 123, 118,
+ 438, 439, 433, 433, 433, 477, 433, 473,
+ 474, 479, 479, 123, 118, 438, 439, 433,
+ 433, 433, 477, 433, 433, 441, 433, 473,
+ 474, 475, 479, 123, 118, 438, 439, 433,
+ 433, 147, 477, 433, 433, 441, 433, 471,
+ 433, 503, 433, 490, 490, 123, 118, 438,
+ 439, 433, 433, 433, 445, 433, 471, 433,
+ 471, 433, 433, 433, 481, 481, 433, 118,
+ 438, 439, 433, 433, 433, 445, 433, 471,
+ 433, 471, 433, 433, 433, 481, 504, 433,
+ 118, 438, 439, 433, 433, 433, 445, 433,
+ 471, 433, 471, 433, 503, 433, 481, 481,
+ 433, 118, 438, 439, 433, 433, 433, 445,
+ 433, 471, 433, 471, 120, 433, 433, 136,
+ 472, 433, 118, 438, 439, 433, 433, 433,
+ 445, 433, 471, 433, 464, 465, 470, 470,
+ 123, 118, 438, 439, 433, 433, 433, 468,
+ 433, 433, 441, 433, 464, 465, 466, 470,
+ 123, 118, 438, 439, 433, 433, 149, 468,
+ 433, 433, 441, 433, 462, 433, 505, 433,
+ 490, 490, 123, 118, 438, 439, 433, 433,
+ 433, 445, 433, 462, 433, 462, 433, 433,
+ 433, 481, 481, 433, 118, 438, 439, 433,
+ 433, 433, 445, 433, 462, 433, 462, 433,
+ 433, 433, 481, 506, 433, 118, 438, 439,
+ 433, 433, 433, 445, 433, 462, 433, 462,
+ 433, 505, 433, 481, 481, 433, 118, 438,
+ 439, 433, 433, 433, 445, 433, 462, 433,
+ 462, 120, 433, 433, 136, 463, 433, 118,
+ 438, 439, 433, 433, 433, 445, 433, 462,
+ 433, 455, 456, 461, 461, 123, 118, 438,
+ 439, 433, 433, 433, 459, 433, 433, 441,
+ 433, 455, 456, 457, 461, 123, 118, 438,
+ 439, 433, 433, 151, 459, 433, 433, 441,
+ 433, 453, 433, 507, 433, 490, 490, 123,
+ 118, 438, 439, 433, 433, 433, 445, 433,
+ 453, 433, 453, 433, 433, 433, 481, 481,
+ 433, 118, 438, 439, 433, 433, 433, 445,
+ 433, 453, 433, 453, 433, 433, 433, 481,
+ 508, 433, 118, 438, 439, 433, 433, 433,
+ 445, 433, 453, 433, 453, 433, 507, 433,
+ 481, 481, 433, 118, 438, 439, 433, 433,
+ 433, 445, 433, 453, 433, 453, 120, 433,
+ 433, 136, 454, 433, 118, 438, 439, 433,
+ 433, 433, 445, 433, 453, 433, 446, 447,
+ 452, 452, 123, 118, 438, 439, 433, 433,
+ 433, 450, 433, 433, 441, 433, 446, 447,
+ 448, 452, 123, 118, 438, 439, 433, 433,
+ 153, 450, 433, 433, 441, 433, 443, 433,
+ 509, 433, 490, 490, 123, 118, 438, 439,
+ 433, 433, 433, 445, 433, 443, 433, 443,
+ 433, 433, 433, 481, 481, 433, 118, 438,
+ 439, 433, 433, 433, 445, 433, 443, 433,
+ 443, 433, 433, 433, 481, 510, 433, 118,
+ 438, 439, 433, 433, 433, 445, 433, 443,
+ 433, 443, 433, 509, 433, 481, 481, 433,
+ 118, 438, 439, 433, 433, 433, 445, 433,
+ 443, 433, 443, 120, 433, 433, 136, 444,
+ 433, 118, 438, 439, 433, 433, 433, 445,
+ 433, 443, 433, 434, 435, 437, 437, 123,
+ 118, 438, 439, 433, 433, 433, 440, 433,
+ 433, 441, 433, 188, 189, 190, 191, 511,
+ 363, 84, 79, 194, 195, 196, 196, 156,
+ 197, 361, 188, 200, 361, 204, 512, 206,
+ 207, 6, 1, 208, 209, 203, 203, 38,
+ 210, 203, 203, 211, 203, 214, 189, 190,
+ 191, 513, 514, 84, 157, 515, 516, 203,
+ 196, 156, 517, 203, 214, 200, 203, 116,
+ 518, 518, 84, 157, 208, 209, 203, 203,
+ 156, 519, 203, 520, 203, 203, 521, 515,
+ 516, 203, 515, 516, 203, 255, 203, 515,
+ 522, 203, 515, 523, 203, 515, 203, 520,
+ 203, 203, 203, 515, 516, 203, 524, 3,
+ 361, 361, 402, 431, 361, 79, 194, 195,
+ 361, 361, 361, 366, 361, 524, 361, 525,
+ 368, 526, 527, 84, 157, 515, 516, 203,
+ 203, 158, 371, 203, 203, 200, 203, 528,
+ 368, 529, 529, 84, 157, 515, 516, 203,
+ 203, 203, 371, 203, 203, 200, 203, 368,
+ 529, 529, 84, 157, 515, 516, 203, 203,
+ 203, 371, 203, 203, 200, 203, 525, 368,
+ 529, 529, 84, 157, 515, 516, 203, 203,
+ 203, 371, 203, 203, 200, 203, 525, 368,
+ 526, 529, 84, 157, 515, 516, 203, 203,
+ 158, 371, 203, 203, 200, 203, 214, 203,
+ 280, 116, 530, 530, 160, 157, 208, 209,
+ 203, 203, 203, 519, 203, 214, 203, 531,
+ 184, 532, 533, 162, 157, 515, 516, 203,
+ 203, 203, 534, 203, 184, 532, 533, 162,
+ 157, 515, 516, 203, 203, 203, 534, 203,
+ 532, 532, 162, 157, 515, 516, 203, 203,
+ 203, 534, 203, 535, 181, 536, 537, 165,
+ 157, 515, 516, 203, 203, 203, 534, 203,
+ 181, 536, 537, 165, 157, 515, 516, 203,
+ 203, 203, 534, 203, 536, 536, 165, 157,
+ 515, 516, 203, 203, 203, 534, 203, 538,
+ 178, 539, 540, 168, 157, 515, 516, 203,
+ 203, 203, 534, 203, 178, 539, 540, 168,
+ 157, 515, 516, 203, 203, 203, 534, 203,
+ 539, 539, 168, 157, 515, 516, 203, 203,
+ 203, 534, 203, 541, 175, 542, 543, 203,
+ 157, 515, 516, 203, 203, 203, 534, 203,
+ 175, 542, 543, 203, 157, 515, 516, 203,
+ 203, 203, 534, 203, 542, 542, 203, 157,
+ 515, 516, 203, 203, 203, 534, 203, 544,
+ 203, 545, 546, 203, 157, 515, 516, 203,
+ 203, 172, 203, 171, 203, 542, 542, 203,
+ 157, 515, 516, 203, 542, 542, 203, 157,
+ 515, 516, 203, 544, 203, 542, 542, 203,
+ 157, 515, 516, 203, 544, 203, 545, 542,
+ 203, 157, 515, 516, 203, 203, 172, 203,
+ 524, 171, 361, 361, 98, 365, 361, 79,
+ 194, 195, 361, 361, 361, 366, 361, 524,
+ 361, 548, 547, 549, 549, 547, 186, 550,
+ 551, 547, 549, 549, 547, 186, 550, 551,
+ 547, 552, 547, 547, 553, 550, 551, 547,
+ 550, 551, 547, 554, 547, 550, 555, 547,
+ 550, 556, 547, 550, 547, 552, 547, 547,
+ 547, 550, 551, 547, 188, 432, 432, 432,
+ 432, 432, 432, 432, 432, 432, 196, 432,
+ 432, 432, 432, 188, 432, 0
};
static const short _indic_syllable_machine_trans_targs[] = {
@@ -1014,51 +1016,51 @@ static const short _indic_syllable_machine_trans_targs[] = {
169, 170, 520, 172, 173, 517, 175, 176,
514, 178, 532, 178, 179, 258, 337, 339,
413, 415, 359, 360, 416, 412, 494, 495,
- 384, 530, 178, 180, 182, 36, 257, 202,
- 203, 255, 227, 181, 35, 183, 251, 1,
- 184, 186, 34, 250, 248, 185, 33, 187,
- 244, 188, 190, 32, 243, 241, 189, 31,
- 191, 237, 192, 194, 30, 236, 234, 193,
- 29, 195, 230, 196, 198, 28, 229, 226,
- 197, 27, 212, 0, 201, 206, 178, 204,
- 205, 208, 2, 211, 3, 214, 6, 24,
- 217, 9, 21, 220, 12, 18, 223, 15,
- 225, 231, 233, 238, 240, 245, 247, 252,
- 254, 178, 259, 261, 73, 334, 281, 282,
- 335, 306, 260, 72, 262, 330, 38, 263,
- 265, 71, 329, 327, 264, 70, 266, 323,
- 267, 269, 69, 322, 320, 268, 68, 270,
- 316, 271, 273, 67, 315, 313, 272, 66,
- 274, 309, 275, 277, 65, 308, 305, 276,
- 64, 291, 37, 280, 285, 178, 283, 284,
- 287, 39, 290, 40, 293, 43, 61, 296,
- 46, 58, 299, 49, 55, 302, 52, 304,
- 310, 312, 317, 319, 324, 326, 331, 333,
- 178, 338, 109, 340, 408, 75, 341, 343,
- 108, 407, 405, 342, 107, 344, 401, 345,
- 347, 106, 400, 398, 346, 105, 348, 394,
- 349, 351, 104, 393, 391, 350, 103, 352,
- 387, 353, 355, 102, 386, 383, 354, 101,
- 369, 74, 358, 363, 178, 361, 362, 365,
- 76, 368, 77, 371, 80, 98, 374, 83,
- 95, 377, 86, 92, 380, 89, 382, 388,
- 390, 395, 397, 402, 404, 409, 411, 178,
- 178, 417, 419, 146, 145, 439, 440, 492,
- 464, 418, 420, 488, 111, 421, 423, 144,
- 487, 485, 422, 143, 424, 481, 425, 427,
- 142, 480, 478, 426, 141, 428, 474, 429,
- 431, 140, 473, 471, 430, 139, 432, 467,
- 433, 435, 138, 466, 463, 434, 137, 449,
- 110, 438, 443, 178, 441, 442, 445, 112,
- 448, 113, 451, 116, 134, 454, 119, 131,
- 457, 122, 128, 460, 125, 462, 468, 470,
- 475, 477, 482, 484, 489, 491, 147, 496,
- 497, 511, 500, 501, 529, 148, 505, 499,
- 504, 502, 503, 506, 507, 150, 510, 508,
- 149, 151, 513, 153, 174, 163, 516, 156,
- 171, 519, 159, 168, 522, 162, 165, 525,
- 164, 528, 178, 531, 177, 534, 535, 533,
- 538, 178, 536, 537
+ 384, 530, 539, 178, 180, 182, 36, 257,
+ 202, 203, 255, 227, 181, 35, 183, 251,
+ 1, 184, 186, 34, 250, 248, 185, 33,
+ 187, 244, 188, 190, 32, 243, 241, 189,
+ 31, 191, 237, 192, 194, 30, 236, 234,
+ 193, 29, 195, 230, 196, 198, 28, 229,
+ 226, 197, 27, 212, 0, 201, 206, 178,
+ 204, 205, 208, 2, 211, 3, 214, 6,
+ 24, 217, 9, 21, 220, 12, 18, 223,
+ 15, 225, 231, 233, 238, 240, 245, 247,
+ 252, 254, 178, 259, 261, 73, 334, 281,
+ 282, 335, 306, 260, 72, 262, 330, 38,
+ 263, 265, 71, 329, 327, 264, 70, 266,
+ 323, 267, 269, 69, 322, 320, 268, 68,
+ 270, 316, 271, 273, 67, 315, 313, 272,
+ 66, 274, 309, 275, 277, 65, 308, 305,
+ 276, 64, 291, 37, 280, 285, 178, 283,
+ 284, 287, 39, 290, 40, 293, 43, 61,
+ 296, 46, 58, 299, 49, 55, 302, 52,
+ 304, 310, 312, 317, 319, 324, 326, 331,
+ 333, 178, 338, 109, 340, 408, 75, 341,
+ 343, 108, 407, 405, 342, 107, 344, 401,
+ 345, 347, 106, 400, 398, 346, 105, 348,
+ 394, 349, 351, 104, 393, 391, 350, 103,
+ 352, 387, 353, 355, 102, 386, 383, 354,
+ 101, 369, 74, 358, 363, 178, 361, 362,
+ 365, 76, 368, 77, 371, 80, 98, 374,
+ 83, 95, 377, 86, 92, 380, 89, 382,
+ 388, 390, 395, 397, 402, 404, 409, 411,
+ 178, 178, 417, 419, 146, 145, 439, 440,
+ 492, 464, 418, 420, 488, 111, 421, 423,
+ 144, 487, 485, 422, 143, 424, 481, 425,
+ 427, 142, 480, 478, 426, 141, 428, 474,
+ 429, 431, 140, 473, 471, 430, 139, 432,
+ 467, 433, 435, 138, 466, 463, 434, 137,
+ 449, 110, 438, 443, 178, 441, 442, 445,
+ 112, 448, 113, 451, 116, 134, 454, 119,
+ 131, 457, 122, 128, 460, 125, 462, 468,
+ 470, 475, 477, 482, 484, 489, 491, 147,
+ 496, 497, 511, 500, 501, 529, 148, 505,
+ 499, 504, 502, 503, 506, 507, 150, 510,
+ 508, 149, 151, 513, 153, 174, 163, 516,
+ 156, 171, 519, 159, 168, 522, 162, 165,
+ 525, 164, 528, 178, 531, 177, 534, 535,
+ 533, 538, 178, 536, 537
};
static const char _indic_syllable_machine_trans_actions[] = {
@@ -1087,51 +1089,51 @@ static const char _indic_syllable_machine_trans_actions[] = {
0, 0, 2, 0, 0, 2, 0, 0,
2, 9, 0, 12, 2, 2, 6, 2,
13, 13, 0, 0, 2, 2, 6, 2,
- 6, 2, 14, 2, 2, 0, 2, 0,
+ 6, 2, 0, 14, 2, 2, 0, 2,
+ 0, 0, 2, 2, 2, 0, 2, 2,
+ 0, 2, 2, 0, 2, 2, 2, 0,
+ 2, 2, 2, 2, 0, 2, 2, 2,
+ 0, 2, 2, 2, 2, 0, 2, 2,
+ 2, 0, 2, 2, 2, 2, 0, 2,
+ 2, 2, 0, 2, 0, 0, 0, 15,
+ 0, 0, 2, 0, 2, 0, 2, 0,
+ 0, 2, 0, 0, 2, 0, 0, 2,
+ 0, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 16, 2, 2, 0, 2, 0,
0, 2, 2, 2, 0, 2, 2, 0,
2, 2, 0, 2, 2, 2, 0, 2,
2, 2, 2, 0, 2, 2, 2, 0,
2, 2, 2, 2, 0, 2, 2, 2,
0, 2, 2, 2, 2, 0, 2, 2,
- 2, 0, 2, 0, 0, 0, 15, 0,
+ 2, 0, 2, 0, 0, 0, 17, 0,
0, 2, 0, 2, 0, 2, 0, 0,
2, 0, 0, 2, 0, 0, 2, 0,
2, 2, 2, 2, 2, 2, 2, 2,
- 2, 16, 2, 2, 0, 2, 0, 0,
- 2, 2, 2, 0, 2, 2, 0, 2,
- 2, 0, 2, 2, 2, 0, 2, 2,
- 2, 2, 0, 2, 2, 2, 0, 2,
- 2, 2, 2, 0, 2, 2, 2, 0,
- 2, 2, 2, 2, 0, 2, 2, 2,
- 0, 2, 0, 0, 0, 17, 0, 0,
- 2, 0, 2, 0, 2, 0, 0, 2,
- 0, 0, 2, 0, 0, 2, 0, 2,
- 2, 2, 2, 2, 2, 2, 2, 2,
- 18, 6, 0, 6, 6, 0, 6, 2,
- 0, 6, 2, 6, 0, 6, 6, 6,
+ 2, 18, 6, 0, 6, 6, 0, 6,
2, 0, 6, 2, 6, 0, 6, 6,
6, 2, 0, 6, 2, 6, 0, 6,
6, 6, 2, 0, 6, 2, 6, 0,
- 6, 0, 0, 0, 19, 0, 0, 2,
- 0, 2, 0, 2, 0, 0, 2, 0,
- 0, 2, 0, 0, 2, 0, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 20,
- 21, 2, 2, 0, 0, 0, 0, 2,
- 2, 2, 2, 2, 0, 2, 2, 0,
- 2, 2, 2, 0, 2, 2, 2, 2,
+ 6, 6, 6, 2, 0, 6, 2, 6,
+ 0, 6, 0, 0, 0, 19, 0, 0,
+ 2, 0, 2, 0, 2, 0, 0, 2,
+ 0, 0, 2, 0, 0, 2, 0, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 20, 21, 2, 2, 0, 0, 0, 0,
+ 2, 2, 2, 2, 2, 0, 2, 2,
0, 2, 2, 2, 0, 2, 2, 2,
2, 0, 2, 2, 2, 0, 2, 2,
2, 2, 0, 2, 2, 2, 0, 2,
- 0, 0, 0, 22, 0, 0, 2, 0,
- 2, 0, 2, 0, 0, 2, 0, 0,
- 2, 0, 0, 2, 0, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 0, 0,
- 8, 2, 0, 0, 2, 0, 2, 0,
- 0, 0, 0, 8, 8, 0, 8, 8,
- 0, 0, 2, 0, 0, 0, 2, 0,
- 0, 2, 0, 0, 2, 0, 0, 2,
- 0, 2, 23, 2, 0, 0, 0, 0,
- 0, 24, 0, 0
+ 2, 2, 2, 0, 2, 2, 2, 0,
+ 2, 0, 0, 0, 22, 0, 0, 2,
+ 0, 2, 0, 2, 0, 0, 2, 0,
+ 0, 2, 0, 0, 2, 0, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 0,
+ 0, 8, 2, 0, 0, 2, 0, 2,
+ 0, 0, 0, 0, 8, 8, 0, 8,
+ 8, 0, 0, 2, 0, 0, 0, 2,
+ 0, 0, 2, 0, 0, 2, 0, 0,
+ 2, 0, 2, 23, 2, 0, 0, 0,
+ 0, 0, 24, 0, 0
};
static const char _indic_syllable_machine_to_state_actions[] = {
@@ -1202,7 +1204,7 @@ static const char _indic_syllable_machine_to_state_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0
+ 0, 0, 0, 0
};
static const char _indic_syllable_machine_from_state_actions[] = {
@@ -1273,7 +1275,7 @@ static const char _indic_syllable_machine_from_state_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0
+ 0, 0, 0, 0
};
static const short _indic_syllable_machine_eof_trans[] = {
@@ -1299,52 +1301,52 @@ static const short _indic_syllable_machine_eof_trans[] = {
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
- 1, 186, 0, 203, 203, 203, 203, 203,
- 203, 203, 203, 203, 203, 203, 203, 203,
- 203, 203, 203, 203, 203, 203, 203, 203,
- 203, 203, 203, 203, 203, 203, 203, 203,
- 203, 203, 203, 203, 203, 203, 203, 203,
- 203, 203, 203, 203, 203, 203, 203, 203,
- 203, 203, 203, 203, 203, 203, 203, 203,
- 203, 203, 203, 203, 203, 203, 203, 203,
- 203, 203, 203, 203, 203, 203, 203, 203,
- 203, 203, 203, 203, 203, 203, 203, 203,
- 203, 203, 282, 282, 282, 282, 282, 282,
- 282, 282, 282, 282, 282, 282, 282, 282,
- 282, 282, 282, 282, 282, 282, 282, 282,
- 282, 282, 282, 282, 282, 282, 282, 282,
- 282, 282, 282, 282, 282, 282, 282, 282,
- 282, 282, 282, 282, 282, 282, 282, 282,
- 282, 282, 282, 282, 282, 282, 282, 282,
- 282, 282, 282, 282, 282, 282, 282, 282,
- 282, 282, 282, 282, 282, 282, 282, 282,
- 282, 282, 282, 282, 282, 282, 282, 282,
- 282, 361, 361, 361, 361, 361, 361, 361,
- 361, 361, 361, 361, 361, 361, 361, 361,
- 361, 361, 361, 361, 361, 361, 361, 361,
- 361, 361, 361, 361, 361, 361, 361, 361,
- 361, 361, 361, 361, 361, 361, 361, 361,
- 361, 361, 361, 361, 361, 361, 361, 361,
- 361, 361, 361, 361, 361, 361, 361, 361,
- 361, 361, 361, 361, 361, 361, 361, 361,
- 361, 361, 361, 361, 361, 361, 361, 361,
- 361, 361, 361, 361, 361, 432, 361, 432,
- 433, 433, 433, 433, 433, 433, 433, 433,
- 433, 433, 433, 433, 433, 433, 433, 433,
- 433, 433, 433, 433, 433, 433, 433, 433,
- 433, 433, 433, 433, 433, 433, 433, 433,
- 433, 433, 433, 433, 433, 433, 433, 433,
- 433, 433, 433, 433, 433, 433, 433, 433,
- 433, 433, 433, 433, 433, 433, 433, 433,
- 433, 433, 433, 433, 433, 433, 433, 433,
- 433, 433, 433, 433, 433, 433, 433, 433,
- 433, 433, 433, 433, 433, 433, 361, 203,
- 203, 203, 203, 203, 203, 203, 203, 203,
- 203, 361, 203, 203, 203, 203, 203, 203,
- 203, 203, 203, 203, 203, 203, 203, 203,
- 203, 203, 203, 203, 203, 203, 203, 203,
- 203, 361, 547, 547, 547, 547, 547, 547,
- 547, 547, 547
+ 1, 186, 0, 204, 204, 204, 204, 204,
+ 204, 204, 204, 204, 204, 204, 204, 204,
+ 204, 204, 204, 204, 204, 204, 204, 204,
+ 204, 204, 204, 204, 204, 204, 204, 204,
+ 204, 204, 204, 204, 204, 204, 204, 204,
+ 204, 204, 204, 204, 204, 204, 204, 204,
+ 204, 204, 204, 204, 204, 204, 204, 204,
+ 204, 204, 204, 204, 204, 204, 204, 204,
+ 204, 204, 204, 204, 204, 204, 204, 204,
+ 204, 204, 204, 204, 204, 204, 204, 204,
+ 204, 204, 283, 283, 283, 283, 283, 283,
+ 283, 283, 283, 283, 283, 283, 283, 283,
+ 283, 283, 283, 283, 283, 283, 283, 283,
+ 283, 283, 283, 283, 283, 283, 283, 283,
+ 283, 283, 283, 283, 283, 283, 283, 283,
+ 283, 283, 283, 283, 283, 283, 283, 283,
+ 283, 283, 283, 283, 283, 283, 283, 283,
+ 283, 283, 283, 283, 283, 283, 283, 283,
+ 283, 283, 283, 283, 283, 283, 283, 283,
+ 283, 283, 283, 283, 283, 283, 283, 283,
+ 283, 362, 362, 362, 362, 362, 362, 362,
+ 362, 362, 362, 362, 362, 362, 362, 362,
+ 362, 362, 362, 362, 362, 362, 362, 362,
+ 362, 362, 362, 362, 362, 362, 362, 362,
+ 362, 362, 362, 362, 362, 362, 362, 362,
+ 362, 362, 362, 362, 362, 362, 362, 362,
+ 362, 362, 362, 362, 362, 362, 362, 362,
+ 362, 362, 362, 362, 362, 362, 362, 362,
+ 362, 362, 362, 362, 362, 362, 362, 362,
+ 362, 362, 362, 362, 362, 433, 362, 433,
+ 434, 434, 434, 434, 434, 434, 434, 434,
+ 434, 434, 434, 434, 434, 434, 434, 434,
+ 434, 434, 434, 434, 434, 434, 434, 434,
+ 434, 434, 434, 434, 434, 434, 434, 434,
+ 434, 434, 434, 434, 434, 434, 434, 434,
+ 434, 434, 434, 434, 434, 434, 434, 434,
+ 434, 434, 434, 434, 434, 434, 434, 434,
+ 434, 434, 434, 434, 434, 434, 434, 434,
+ 434, 434, 434, 434, 434, 434, 434, 434,
+ 434, 434, 434, 434, 434, 434, 362, 204,
+ 204, 204, 204, 204, 204, 204, 204, 204,
+ 204, 362, 204, 204, 204, 204, 204, 204,
+ 204, 204, 204, 204, 204, 204, 204, 204,
+ 204, 204, 204, 204, 204, 204, 204, 204,
+ 204, 362, 548, 548, 548, 548, 548, 548,
+ 548, 548, 548, 433
};
static const int indic_syllable_machine_start = 178;
@@ -1358,7 +1360,7 @@ static const int indic_syllable_machine_en_main = 178;
-#line 96 "hb-ot-shape-complex-indic-machine.rl"
+#line 97 "hb-ot-shape-complex-indic-machine.rl"
#define found_syllable(syllable_type) \
@@ -1378,7 +1380,7 @@ find_syllables (hb_buffer_t *buffer)
int cs;
hb_glyph_info_t *info = buffer->info;
-#line 1382 "hb-ot-shape-complex-indic-machine.hh"
+#line 1384 "hb-ot-shape-complex-indic-machine.hh"
{
cs = indic_syllable_machine_start;
ts = 0;
@@ -1386,7 +1388,7 @@ find_syllables (hb_buffer_t *buffer)
act = 0;
}
-#line 117 "hb-ot-shape-complex-indic-machine.rl"
+#line 118 "hb-ot-shape-complex-indic-machine.rl"
p = 0;
@@ -1395,7 +1397,7 @@ find_syllables (hb_buffer_t *buffer)
unsigned int last = 0;
unsigned int syllable_serial = 1;
-#line 1399 "hb-ot-shape-complex-indic-machine.hh"
+#line 1401 "hb-ot-shape-complex-indic-machine.hh"
{
int _slen;
int _trans;
@@ -1409,7 +1411,7 @@ _resume:
#line 1 "NONE"
{ts = p;}
break;
-#line 1413 "hb-ot-shape-complex-indic-machine.hh"
+#line 1415 "hb-ot-shape-complex-indic-machine.hh"
}
_keys = _indic_syllable_machine_trans_keys + (cs<<1);
@@ -1432,71 +1434,71 @@ _eof_trans:
{te = p+1;}
break;
case 15:
-#line 87 "hb-ot-shape-complex-indic-machine.rl"
+#line 88 "hb-ot-shape-complex-indic-machine.rl"
{te = p+1;{ found_syllable (consonant_syllable); }}
break;
case 17:
-#line 88 "hb-ot-shape-complex-indic-machine.rl"
+#line 89 "hb-ot-shape-complex-indic-machine.rl"
{te = p+1;{ found_syllable (vowel_syllable); }}
break;
case 22:
-#line 89 "hb-ot-shape-complex-indic-machine.rl"
+#line 90 "hb-ot-shape-complex-indic-machine.rl"
{te = p+1;{ found_syllable (standalone_cluster); }}
break;
case 24:
-#line 90 "hb-ot-shape-complex-indic-machine.rl"
+#line 91 "hb-ot-shape-complex-indic-machine.rl"
{te = p+1;{ found_syllable (symbol_cluster); }}
break;
case 19:
-#line 91 "hb-ot-shape-complex-indic-machine.rl"
+#line 92 "hb-ot-shape-complex-indic-machine.rl"
{te = p+1;{ found_syllable (broken_cluster); }}
break;
case 12:
-#line 92 "hb-ot-shape-complex-indic-machine.rl"
+#line 93 "hb-ot-shape-complex-indic-machine.rl"
{te = p+1;{ found_syllable (non_indic_cluster); }}
break;
case 14:
-#line 87 "hb-ot-shape-complex-indic-machine.rl"
+#line 88 "hb-ot-shape-complex-indic-machine.rl"
{te = p;p--;{ found_syllable (consonant_syllable); }}
break;
case 16:
-#line 88 "hb-ot-shape-complex-indic-machine.rl"
+#line 89 "hb-ot-shape-complex-indic-machine.rl"
{te = p;p--;{ found_syllable (vowel_syllable); }}
break;
case 21:
-#line 89 "hb-ot-shape-complex-indic-machine.rl"
+#line 90 "hb-ot-shape-complex-indic-machine.rl"
{te = p;p--;{ found_syllable (standalone_cluster); }}
break;
case 23:
-#line 90 "hb-ot-shape-complex-indic-machine.rl"
+#line 91 "hb-ot-shape-complex-indic-machine.rl"
{te = p;p--;{ found_syllable (symbol_cluster); }}
break;
case 18:
-#line 91 "hb-ot-shape-complex-indic-machine.rl"
+#line 92 "hb-ot-shape-complex-indic-machine.rl"
{te = p;p--;{ found_syllable (broken_cluster); }}
break;
case 20:
-#line 92 "hb-ot-shape-complex-indic-machine.rl"
+#line 93 "hb-ot-shape-complex-indic-machine.rl"
{te = p;p--;{ found_syllable (non_indic_cluster); }}
break;
case 1:
-#line 87 "hb-ot-shape-complex-indic-machine.rl"
+#line 88 "hb-ot-shape-complex-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (consonant_syllable); }}
break;
case 3:
-#line 88 "hb-ot-shape-complex-indic-machine.rl"
+#line 89 "hb-ot-shape-complex-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (vowel_syllable); }}
break;
case 7:
-#line 89 "hb-ot-shape-complex-indic-machine.rl"
+#line 90 "hb-ot-shape-complex-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (standalone_cluster); }}
break;
case 9:
-#line 90 "hb-ot-shape-complex-indic-machine.rl"
+#line 91 "hb-ot-shape-complex-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (symbol_cluster); }}
break;
case 4:
-#line 91 "hb-ot-shape-complex-indic-machine.rl"
+#line 92 "hb-ot-shape-complex-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (broken_cluster); }}
break;
case 5:
@@ -1517,22 +1519,22 @@ _eof_trans:
case 8:
#line 1 "NONE"
{te = p+1;}
-#line 87 "hb-ot-shape-complex-indic-machine.rl"
+#line 88 "hb-ot-shape-complex-indic-machine.rl"
{act = 1;}
break;
case 6:
#line 1 "NONE"
{te = p+1;}
-#line 91 "hb-ot-shape-complex-indic-machine.rl"
+#line 92 "hb-ot-shape-complex-indic-machine.rl"
{act = 5;}
break;
case 13:
#line 1 "NONE"
{te = p+1;}
-#line 92 "hb-ot-shape-complex-indic-machine.rl"
+#line 93 "hb-ot-shape-complex-indic-machine.rl"
{act = 6;}
break;
-#line 1536 "hb-ot-shape-complex-indic-machine.hh"
+#line 1538 "hb-ot-shape-complex-indic-machine.hh"
}
_again:
@@ -1541,7 +1543,7 @@ _again:
#line 1 "NONE"
{ts = 0;}
break;
-#line 1545 "hb-ot-shape-complex-indic-machine.hh"
+#line 1547 "hb-ot-shape-complex-indic-machine.hh"
}
if ( ++p != pe )
@@ -1557,7 +1559,7 @@ _again:
}
-#line 126 "hb-ot-shape-complex-indic-machine.rl"
+#line 127 "hb-ot-shape-complex-indic-machine.rl"
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh
index 5879c3e491..a1e0d5266b 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh
@@ -60,7 +60,8 @@ enum indic_category_t {
OT_Repha = 15, /* Atomically-encoded logical or visual repha. */
OT_Ra = 16,
OT_CM = 17, /* Consonant-Medial. */
- OT_Symbol = 18 /* Avagraha, etc that take marks (SM,A,VD). */
+ OT_Symbol = 18, /* Avagraha, etc that take marks (SM,A,VD). */
+ OT_CS = 19
};
#define MEDIAL_FLAGS (FLAG (OT_CM))
@@ -70,7 +71,7 @@ enum indic_category_t {
* We treat Vowels and placeholders as if they were consonants. This is safe because Vowels
* cannot happen in a consonant syllable. The plus side however is, we can call the
* consonant syllable logic from the vowel syllable function and get it all right! */
-#define CONSONANT_FLAGS (FLAG (OT_C) | FLAG (OT_Ra) | MEDIAL_FLAGS | FLAG (OT_V) | FLAG (OT_PLACEHOLDER) | FLAG (OT_DOTTEDCIRCLE))
+#define CONSONANT_FLAGS (FLAG (OT_C) | FLAG (OT_CS) | FLAG (OT_Ra) | MEDIAL_FLAGS | FLAG (OT_V) | FLAG (OT_PLACEHOLDER) | FLAG (OT_DOTTEDCIRCLE))
#define JOINER_FLAGS (FLAG (OT_ZWJ) | FLAG (OT_ZWNJ))
#define HALANT_OR_COENG_FLAGS (FLAG (OT_H) | FLAG (OT_Coeng))
@@ -121,8 +122,8 @@ enum indic_syllabic_category_t {
INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED = OT_X, /* Don't care. */
INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED = OT_CM,
INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA = OT_N,
- INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER = OT_Repha, /* TODO */
- INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK = OT_SM,
+ INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER = OT_CS,
+ INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK = OT_SM, /* https://github.com/harfbuzz/harfbuzz/issues/552 */
INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER = OT_Coeng,
INDIC_SYLLABIC_CATEGORY_JOINER = OT_ZWJ,
INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER = OT_X,
@@ -132,7 +133,7 @@ enum indic_syllabic_category_t {
INDIC_SYLLABIC_CATEGORY_NUMBER_JOINER = OT_PLACEHOLDER, /* Don't care. */
INDIC_SYLLABIC_CATEGORY_PURE_KILLER = OT_M, /* Is like a vowel matra. */
INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER = OT_RS,
- INDIC_SYLLABIC_CATEGORY_SYLLABLE_MODIFIER = OT_M, /* Misc Khmer signs. */
+ INDIC_SYLLABIC_CATEGORY_SYLLABLE_MODIFIER = OT_SM,
INDIC_SYLLABIC_CATEGORY_TONE_LETTER = OT_X,
INDIC_SYLLABIC_CATEGORY_TONE_MARK = OT_N,
INDIC_SYLLABIC_CATEGORY_VIRAMA = OT_H,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-table.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-table.cc
index 80a6b25e3b..bfd1c6d342 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-table.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-table.cc
@@ -6,61 +6,62 @@
*
* on files with these headers:
*
- * # IndicSyllabicCategory-9.0.0.txt
- * # Date: 2016-05-21, 02:46:00 GMT [RP]
- * # IndicPositionalCategory-9.0.0.txt
- * # Date: 2016-02-25, 00:48:00 GMT [RP]
- * # Blocks-9.0.0.txt
- * # Date: 2016-02-05, 23:48:00 GMT [KW]
+ * # IndicSyllabicCategory-10.0.0.txt
+ * # Date: 2017-05-31, 01:07:00 GMT [KW, RP]
+ * # IndicPositionalCategory-10.0.0.txt
+ * # Date: 2017-05-31, 01:07:00 GMT [RP]
+ * # Blocks-10.0.0.txt
+ * # Date: 2017-04-12, 17:30:00 GMT [KW]
*/
#include "hb-ot-shape-complex-indic-private.hh"
#define ISC_A INDIC_SYLLABIC_CATEGORY_AVAGRAHA /* 15 chars; Avagraha */
-#define ISC_Bi INDIC_SYLLABIC_CATEGORY_BINDU /* 67 chars; Bindu */
+#define ISC_Bi INDIC_SYLLABIC_CATEGORY_BINDU /* 80 chars; Bindu */
#define ISC_BJN INDIC_SYLLABIC_CATEGORY_BRAHMI_JOINING_NUMBER /* 20 chars; Brahmi_Joining_Number */
-#define ISC_Ca INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK /* 53 chars; Cantillation_Mark */
-#define ISC_C INDIC_SYLLABIC_CATEGORY_CONSONANT /* 1907 chars; Consonant */
+#define ISC_Ca INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK /* 57 chars; Cantillation_Mark */
+#define ISC_C INDIC_SYLLABIC_CATEGORY_CONSONANT /* 2024 chars; Consonant */
#define ISC_CD INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD /* 10 chars; Consonant_Dead */
-#define ISC_CF INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL /* 62 chars; Consonant_Final */
+#define ISC_CF INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL /* 68 chars; Consonant_Final */
#define ISC_CHL INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER /* 5 chars; Consonant_Head_Letter */
#define ISC_CK INDIC_SYLLABIC_CATEGORY_CONSONANT_KILLER /* 2 chars; Consonant_Killer */
-#define ISC_CM INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL /* 22 chars; Consonant_Medial */
-#define ISC_CP INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER /* 16 chars; Consonant_Placeholder */
-#define ISC_CPR INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA /* 1 chars; Consonant_Preceding_Repha */
-#define ISC_CPrf INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED /* 2 chars; Consonant_Prefixed */
-#define ISC_CS INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED /* 90 chars; Consonant_Subjoined */
-#define ISC_CSR INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA /* 4 chars; Consonant_Succeeding_Repha */
+#define ISC_CM INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL /* 27 chars; Consonant_Medial */
+#define ISC_CP INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER /* 18 chars; Consonant_Placeholder */
+#define ISC_CPR INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA /* 2 chars; Consonant_Preceding_Repha */
+#define ISC_CPrf INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED /* 7 chars; Consonant_Prefixed */
+#define ISC_CS INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED /* 95 chars; Consonant_Subjoined */
+#define ISC_CSR INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA /* 5 chars; Consonant_Succeeding_Repha */
#define ISC_CWS INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER /* 4 chars; Consonant_With_Stacker */
-#define ISC_GM INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK /* 2 chars; Gemination_Mark */
-#define ISC_IS INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER /* 7 chars; Invisible_Stacker */
+#define ISC_GM INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK /* 3 chars; Gemination_Mark */
+#define ISC_IS INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER /* 10 chars; Invisible_Stacker */
#define ISC_ZWJ INDIC_SYLLABIC_CATEGORY_JOINER /* 1 chars; Joiner */
#define ISC_ML INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER /* 1 chars; Modifying_Letter */
#define ISC_ZWNJ INDIC_SYLLABIC_CATEGORY_NON_JOINER /* 1 chars; Non_Joiner */
-#define ISC_N INDIC_SYLLABIC_CATEGORY_NUKTA /* 24 chars; Nukta */
-#define ISC_Nd INDIC_SYLLABIC_CATEGORY_NUMBER /* 459 chars; Number */
+#define ISC_N INDIC_SYLLABIC_CATEGORY_NUKTA /* 28 chars; Nukta */
+#define ISC_Nd INDIC_SYLLABIC_CATEGORY_NUMBER /* 469 chars; Number */
#define ISC_NJ INDIC_SYLLABIC_CATEGORY_NUMBER_JOINER /* 1 chars; Number_Joiner */
#define ISC_x INDIC_SYLLABIC_CATEGORY_OTHER /* 1 chars; Other */
-#define ISC_PK INDIC_SYLLABIC_CATEGORY_PURE_KILLER /* 16 chars; Pure_Killer */
+#define ISC_PK INDIC_SYLLABIC_CATEGORY_PURE_KILLER /* 21 chars; Pure_Killer */
#define ISC_RS INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER /* 2 chars; Register_Shifter */
#define ISC_SM INDIC_SYLLABIC_CATEGORY_SYLLABLE_MODIFIER /* 22 chars; Syllable_Modifier */
#define ISC_TL INDIC_SYLLABIC_CATEGORY_TONE_LETTER /* 7 chars; Tone_Letter */
#define ISC_TM INDIC_SYLLABIC_CATEGORY_TONE_MARK /* 42 chars; Tone_Mark */
#define ISC_V INDIC_SYLLABIC_CATEGORY_VIRAMA /* 24 chars; Virama */
-#define ISC_Vs INDIC_SYLLABIC_CATEGORY_VISARGA /* 31 chars; Visarga */
+#define ISC_Vs INDIC_SYLLABIC_CATEGORY_VISARGA /* 34 chars; Visarga */
#define ISC_Vo INDIC_SYLLABIC_CATEGORY_VOWEL /* 30 chars; Vowel */
-#define ISC_M INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT /* 602 chars; Vowel_Dependent */
-#define ISC_VI INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT /* 431 chars; Vowel_Independent */
+#define ISC_M INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT /* 633 chars; Vowel_Dependent */
+#define ISC_VI INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT /* 443 chars; Vowel_Independent */
-#define IMC_B INDIC_MATRA_CATEGORY_BOTTOM /* 300 chars; Bottom */
+#define IMC_B INDIC_MATRA_CATEGORY_BOTTOM /* 330 chars; Bottom */
+#define IMC_BL INDIC_MATRA_CATEGORY_BOTTOM_AND_LEFT /* 1 chars; Bottom_And_Left */
#define IMC_BR INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT /* 2 chars; Bottom_And_Right */
#define IMC_L INDIC_MATRA_CATEGORY_LEFT /* 57 chars; Left */
#define IMC_LR INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT /* 21 chars; Left_And_Right */
#define IMC_x INDIC_MATRA_CATEGORY_NOT_APPLICABLE /* 1 chars; Not_Applicable */
#define IMC_O INDIC_MATRA_CATEGORY_OVERSTRUCK /* 10 chars; Overstruck */
-#define IMC_R INDIC_MATRA_CATEGORY_RIGHT /* 258 chars; Right */
-#define IMC_T INDIC_MATRA_CATEGORY_TOP /* 342 chars; Top */
+#define IMC_R INDIC_MATRA_CATEGORY_RIGHT /* 262 chars; Right */
+#define IMC_T INDIC_MATRA_CATEGORY_TOP /* 380 chars; Top */
#define IMC_TB INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM /* 10 chars; Top_And_Bottom */
#define IMC_TBR INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT /* 1 chars; Top_And_Bottom_And_Right */
#define IMC_TL INDIC_MATRA_CATEGORY_TOP_AND_LEFT /* 6 chars; Top_And_Left */
@@ -133,7 +134,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {
/* 09E0 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
/* 09E8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
/* 09F0 */ _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
- /* 09F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 09F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(Bi,x), _(x,x), _(x,x), _(x,x),
/* Gurmukhi */
@@ -171,7 +172,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {
/* 0AE0 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x),
/* 0AE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
/* 0AF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
- /* 0AF8 */ _(x,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* 0AF8 */ _(x,x), _(C,x), _(Ca,T), _(Ca,T), _(Ca,T), _(N,T), _(N,T), _(N,T),
/* Oriya */
@@ -251,14 +252,14 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {
/* Malayalam */
- /* 0D00 */ _(x,x), _(Bi,T), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x),
+ /* 0D00 */ _(Bi,T), _(Bi,T), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x),
/* 0D08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x),
/* 0D10 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
/* 0D18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
/* 0D20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
/* 0D28 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
/* 0D30 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
- /* 0D38 */ _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(A,x), _(M,R), _(M,R),
+ /* 0D38 */ _(C,x), _(C,x), _(C,x), _(PK,T), _(PK,T), _(A,x), _(M,R), _(M,R),
/* 0D40 */ _(M,R), _(M,R), _(M,R), _(M,B), _(M,B), _(x,x), _(M,L), _(M,L),
/* 0D48 */ _(M,L), _(x,x), _(M,LR), _(M,LR), _(M,LR), _(V,T),_(CPR,x), _(x,x),
/* 0D50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(CD,x), _(CD,x), _(CD,x), _(M,R),
@@ -341,7 +342,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {
/* 1CD8 */ _(Ca,B), _(Ca,B), _(Ca,T), _(Ca,T), _(Ca,B), _(Ca,B), _(Ca,B), _(Ca,B),
/* 1CE0 */ _(Ca,T), _(Ca,R), _(x,O), _(x,O), _(x,O), _(x,O), _(x,O), _(x,O),
/* 1CE8 */ _(x,O), _(x,x), _(x,x), _(x,x), _(x,x), _(x,B), _(x,x), _(x,x),
- /* 1CF0 */ _(x,x), _(x,x), _(Vs,x), _(Vs,x), _(Ca,T), _(x,x), _(x,x), _(x,x),
+ /* 1CF0 */ _(x,x), _(x,x), _(Vs,x), _(Vs,x), _(Ca,T), _(x,x), _(x,x), _(Ca,R),
/* 1CF8 */ _(Ca,x), _(Ca,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
#define indic_offset_0x2008u 1656
@@ -368,7 +369,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {
/* A8E0 */ _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T),
/* A8E8 */ _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T),
- /* A8F0 */ _(Ca,T), _(Ca,T), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
+ /* A8F0 */ _(Ca,T), _(Ca,T), _(Bi,x), _(Bi,x), _(x,x), _(x,x), _(x,x), _(x,x),
#define indic_offset_0xa9e0u 1720
@@ -390,7 +391,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {
/* AA70 */ _(x,x), _(C,x), _(C,x), _(C,x), _(CP,x), _(CP,x), _(CP,x), _(x,x),
/* AA78 */ _(x,x), _(x,x), _(C,x), _(TM,R), _(TM,T), _(TM,R), _(C,x), _(C,x),
-}; /* Table items: 1784; occupancy: 69% */
+}; /* Table items: 1784; occupancy: 70% */
INDIC_TABLE_ELEMENT_TYPE
hb_indic_get_categories (hb_codepoint_t u)
@@ -398,28 +399,28 @@ hb_indic_get_categories (hb_codepoint_t u)
switch (u >> 12)
{
case 0x0u:
- if (hb_in_range (u, 0x0028u, 0x003Fu)) return indic_table[u - 0x0028u + indic_offset_0x0028u];
- if (hb_in_range (u, 0x00B0u, 0x00D7u)) return indic_table[u - 0x00B0u + indic_offset_0x00b0u];
- if (hb_in_range (u, 0x0900u, 0x0DF7u)) return indic_table[u - 0x0900u + indic_offset_0x0900u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x0028u, 0x003Fu)) return indic_table[u - 0x0028u + indic_offset_0x0028u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x00B0u, 0x00D7u)) return indic_table[u - 0x00B0u + indic_offset_0x00b0u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x0900u, 0x0DF7u)) return indic_table[u - 0x0900u + indic_offset_0x0900u];
if (unlikely (u == 0x00A0u)) return _(CP,x);
break;
case 0x1u:
- if (hb_in_range (u, 0x1000u, 0x109Fu)) return indic_table[u - 0x1000u + indic_offset_0x1000u];
- if (hb_in_range (u, 0x1780u, 0x17EFu)) return indic_table[u - 0x1780u + indic_offset_0x1780u];
- if (hb_in_range (u, 0x1CD0u, 0x1CFFu)) return indic_table[u - 0x1CD0u + indic_offset_0x1cd0u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x1000u, 0x109Fu)) return indic_table[u - 0x1000u + indic_offset_0x1000u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x1780u, 0x17EFu)) return indic_table[u - 0x1780u + indic_offset_0x1780u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x1CD0u, 0x1CFFu)) return indic_table[u - 0x1CD0u + indic_offset_0x1cd0u];
break;
case 0x2u:
- if (hb_in_range (u, 0x2008u, 0x2017u)) return indic_table[u - 0x2008u + indic_offset_0x2008u];
- if (hb_in_range (u, 0x2070u, 0x2087u)) return indic_table[u - 0x2070u + indic_offset_0x2070u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x2008u, 0x2017u)) return indic_table[u - 0x2008u + indic_offset_0x2008u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x2070u, 0x2087u)) return indic_table[u - 0x2070u + indic_offset_0x2070u];
if (unlikely (u == 0x25CCu)) return _(CP,x);
break;
case 0xAu:
- if (hb_in_range (u, 0xA8E0u, 0xA8F7u)) return indic_table[u - 0xA8E0u + indic_offset_0xa8e0u];
- if (hb_in_range (u, 0xA9E0u, 0xA9FFu)) return indic_table[u - 0xA9E0u + indic_offset_0xa9e0u];
- if (hb_in_range (u, 0xAA60u, 0xAA7Fu)) return indic_table[u - 0xAA60u + indic_offset_0xaa60u];
+ if (hb_in_range<hb_codepoint_t> (u, 0xA8E0u, 0xA8F7u)) return indic_table[u - 0xA8E0u + indic_offset_0xa8e0u];
+ if (hb_in_range<hb_codepoint_t> (u, 0xA9E0u, 0xA9FFu)) return indic_table[u - 0xA9E0u + indic_offset_0xa9e0u];
+ if (hb_in_range<hb_codepoint_t> (u, 0xAA60u, 0xAA7Fu)) return indic_table[u - 0xAA60u + indic_offset_0xaa60u];
break;
default:
@@ -467,6 +468,7 @@ hb_indic_get_categories (hb_codepoint_t u)
#undef ISC_VI
#undef IMC_B
+#undef IMC_BL
#undef IMC_BR
#undef IMC_L
#undef IMC_LR
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc
index b48fb561c3..97d6d38287 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc
@@ -142,7 +142,7 @@ is_one_of (const hb_glyph_info_t &info, unsigned int flags)
{
/* If it ligated, all bets are off. */
if (_hb_glyph_info_ligated (&info)) return false;
- return !!(FLAG_SAFE (info.indic_category()) & flags);
+ return !!(FLAG_UNSAFE (info.indic_category()) & flags);
}
static inline bool
@@ -177,15 +177,15 @@ set_indic_properties (hb_glyph_info_t &info)
*/
/* The following act more like the Bindus. */
- if (unlikely (hb_in_range (u, 0x0953u, 0x0954u)))
+ if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x0953u, 0x0954u)))
cat = OT_SM;
/* The following act like consonants. */
- else if (unlikely (hb_in_ranges (u, 0x0A72u, 0x0A73u,
+ else if (unlikely (hb_in_ranges<hb_codepoint_t> (u, 0x0A72u, 0x0A73u,
0x1CF5u, 0x1CF6u)))
cat = OT_C;
/* TODO: The following should only be allowed after a Visarga.
* For now, just treat them like regular tone marks. */
- else if (unlikely (hb_in_range (u, 0x1CE2u, 0x1CE8u)))
+ else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x1CE2u, 0x1CE8u)))
cat = OT_A;
/* TODO: The following should only be allowed after some of
* the nasalization marks, maybe only for U+1CE9..U+1CF1.
@@ -193,15 +193,39 @@ set_indic_properties (hb_glyph_info_t &info)
else if (unlikely (u == 0x1CEDu))
cat = OT_A;
/* The following take marks in standalone clusters, similar to Avagraha. */
- else if (unlikely (hb_in_ranges (u, 0xA8F2u, 0xA8F7u,
+ else if (unlikely (hb_in_ranges<hb_codepoint_t> (u, 0xA8F2u, 0xA8F7u,
0x1CE9u, 0x1CECu,
0x1CEEu, 0x1CF1u)))
{
cat = OT_Symbol;
- ASSERT_STATIC ((int) INDIC_SYLLABIC_CATEGORY_AVAGRAHA == OT_Symbol);
+ static_assert (((int) INDIC_SYLLABIC_CATEGORY_AVAGRAHA == OT_Symbol), "");
}
+ else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x17CDu, 0x17D1u) ||
+ u == 0x17CBu || u == 0x17D3u || u == 0x17DDu)) /* Khmer Various signs */
+ {
+ /* These can occur mid-syllable (eg. before matras), even though Unicode marks them as Syllable_Modifier.
+ * https://github.com/roozbehp/unicode-data/issues/5 */
+ cat = OT_M;
+ pos = POS_ABOVE_C;
+ }
+ else if (unlikely (u == 0x0A51u))
+ {
+ /* https://github.com/harfbuzz/harfbuzz/issues/524 */
+ cat = OT_M;
+ pos = POS_BELOW_C;
+ }
+
+ /* According to ScriptExtensions.txt, these Grantha marks may also be used in Tamil,
+ * so the Indic shaper needs to know their categories. */
+ else if (unlikely (u == 0x11301u || u == 0x11303u)) cat = OT_SM;
+ else if (unlikely (u == 0x1133cu)) cat = OT_N;
+
+ else if (unlikely (u == 0x0AFBu)) cat = OT_N; /* https://github.com/harfbuzz/harfbuzz/issues/552 */
+
+ else if (unlikely (u == 0x0980u)) cat = OT_PLACEHOLDER; /* https://github.com/harfbuzz/harfbuzz/issues/538 */
+ else if (unlikely (u == 0x0C80u)) cat = OT_PLACEHOLDER; /* https://github.com/harfbuzz/harfbuzz/pull/623 */
else if (unlikely (u == 0x17C6u)) cat = OT_N; /* Khmer Bindu doesn't like to be repositioned. */
- else if (unlikely (hb_in_range (u, 0x2010u, 0x2011u)))
+ else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x2010u, 0x2011u)))
cat = OT_PLACEHOLDER;
else if (unlikely (u == 0x25CCu)) cat = OT_DOTTEDCIRCLE;
@@ -210,7 +234,7 @@ set_indic_properties (hb_glyph_info_t &info)
* Re-assign position.
*/
- if ((FLAG_SAFE (cat) & CONSONANT_FLAGS))
+ if ((FLAG_UNSAFE (cat) & CONSONANT_FLAGS))
{
pos = POS_BASE_C;
if (is_ra (u))
@@ -220,7 +244,7 @@ set_indic_properties (hb_glyph_info_t &info)
{
pos = matra_position (u, pos);
}
- else if ((FLAG_SAFE (cat) & (FLAG (OT_SM) | FLAG (OT_VD) | FLAG (OT_A) | FLAG (OT_Symbol))))
+ else if ((FLAG_UNSAFE (cat) & (FLAG (OT_SM) | FLAG (OT_VD) | FLAG (OT_A) | FLAG (OT_Symbol))))
{
pos = POS_SMVD;
}
@@ -411,12 +435,12 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
unsigned int i = 0;
map->add_gsub_pause (initial_reordering);
for (; i < INDIC_BASIC_FEATURES; i++) {
- map->add_feature (indic_features[i].tag, 1, indic_features[i].flags | F_MANUAL_ZWJ);
- map->add_gsub_pause (NULL);
+ map->add_feature (indic_features[i].tag, 1, indic_features[i].flags | F_MANUAL_ZWJ | F_MANUAL_ZWNJ);
+ map->add_gsub_pause (nullptr);
}
map->add_gsub_pause (final_reordering);
for (; i < INDIC_NUM_FEATURES; i++) {
- map->add_feature (indic_features[i].tag, 1, indic_features[i].flags | F_MANUAL_ZWJ);
+ map->add_feature (indic_features[i].tag, 1, indic_features[i].flags | F_MANUAL_ZWJ | F_MANUAL_ZWNJ);
}
map->add_global_bool_feature (HB_TAG('c','a','l','t'));
@@ -485,7 +509,7 @@ struct indic_shape_plan_t
/* Our get_nominal_glyph() function needs a font, so we can't get the virama glyph
* during shape planning... Instead, overwrite it here. It's safe. Don't worry! */
- (const_cast<indic_shape_plan_t *> (this))->virama_glyph = glyph;
+ virama_glyph = glyph;
}
*pglyph = glyph;
@@ -495,7 +519,7 @@ struct indic_shape_plan_t
const indic_config_t *config;
bool is_old_spec;
- hb_codepoint_t virama_glyph;
+ mutable hb_codepoint_t virama_glyph;
would_substitute_feature_t rphf;
would_substitute_feature_t pref;
@@ -510,7 +534,7 @@ data_create_indic (const hb_ot_shape_plan_t *plan)
{
indic_shape_plan_t *indic_plan = (indic_shape_plan_t *) calloc (1, sizeof (indic_shape_plan_t));
if (unlikely (!indic_plan))
- return NULL;
+ return nullptr;
indic_plan->config = &indic_configs[0];
for (unsigned int i = 1; i < ARRAY_LENGTH (indic_configs); i++)
@@ -615,6 +639,8 @@ setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_buffer_t *buffer)
{
find_syllables (buffer);
+ foreach_syllable (buffer, start, end)
+ buffer->unsafe_to_break (start, end);
}
static int
@@ -666,6 +692,21 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
hb_glyph_info_t *info = buffer->info;
+ /* https://github.com/harfbuzz/harfbuzz/issues/435#issuecomment-335560167
+ * // For compatibility with legacy usage in Kannada,
+ * // Ra+h+ZWJ must behave like Ra+ZWJ+h...
+ */
+ if (buffer->props.script == HB_SCRIPT_KANNADA &&
+ start + 3 <= end &&
+ is_one_of (info[start ], FLAG (OT_Ra)) &&
+ is_one_of (info[start+1], FLAG (OT_H)) &&
+ is_one_of (info[start+2], FLAG (OT_ZWJ)))
+ {
+ buffer->merge_clusters (start+1, start+3);
+ hb_glyph_info_t tmp = info[start+1];
+ info[start+1] = info[start+2];
+ info[start+2] = tmp;
+ }
/* 1. Find base consonant:
*
@@ -673,7 +714,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
* following algorithm: starting from the end of the syllable, move backwards
* until a consonant is found that does not have a below-base or post-base
* form (post-base forms have to follow below-base forms), or that is not a
- * pre-base reordering Ra, or arrive at the first consonant. The consonant
+ * pre-base-reordering Ra, or arrive at the first consonant. The consonant
* stopped at will be the base.
*
* o If the syllable starts with Ra + Halant (in a script that has Reph)
@@ -744,11 +785,11 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
if (info[i].indic_position() == POS_BELOW_C)
seen_below = true;
- /* -> or that is not a pre-base reordering Ra,
+ /* -> or that is not a pre-base-reordering Ra,
*
* IMPLEMENTATION NOTES:
*
- * Our pre-base reordering Ra's are marked POS_POST_C, so will be skipped
+ * Our pre-base-reordering Ra's are marked POS_POST_C, so will be skipped
* by the logic above already.
*/
@@ -831,8 +872,8 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* 2. Decompose and reorder Matras:
*
- * Each matra and any syllable modifier sign in the cluster are moved to the
- * appropriate position relative to the consonant(s) in the cluster. The
+ * Each matra and any syllable modifier sign in the syllable are moved to the
+ * appropriate position relative to the consonant(s) in the syllable. The
* shaping engine decomposes two- or three-part matras into their constituent
* parts before any repositioning. Matra characters are classified by which
* consonant in a conjunct they have affinity for and are reordered to the
@@ -928,7 +969,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
indic_position_t last_pos = POS_START;
for (unsigned int i = start; i < end; i++)
{
- if ((FLAG_SAFE (info[i].indic_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | MEDIAL_FLAGS | HALANT_OR_COENG_FLAGS)))
+ if ((FLAG_UNSAFE (info[i].indic_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | MEDIAL_FLAGS | HALANT_OR_COENG_FLAGS)))
{
info[i].indic_position() = last_pos;
if (unlikely (info[i].indic_category() == OT_H &&
@@ -1083,7 +1124,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
unsigned int pref_len = 2;
if (indic_plan->mask_array[PREF] && base + pref_len < end)
{
- /* Find a Halant,Ra sequence and mark it for pre-base reordering processing. */
+ /* Find a Halant,Ra sequence and mark it for pre-base-reordering processing. */
for (unsigned int i = base + 1; i + pref_len - 1 < end; i++) {
hb_codepoint_t glyphs[2];
for (unsigned int j = 0; j < pref_len; j++)
@@ -1258,7 +1299,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
/* This function relies heavily on halant glyphs. Lots of ligation
- * and possibly multiplication substitutions happened prior to this
+ * and possibly multiple substitutions happened prior to this
* phase, and that might have messed up our properties. Recover
* from a particular case of that where we're fairly sure that a
* class of OT_H is desired but has been lost. */
@@ -1282,7 +1323,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
* After the localized forms and basic shaping forms GSUB features have been
* applied (see below), the shaping engine performs some final glyph
* reordering before applying all the remaining font features to the entire
- * cluster.
+ * syllable.
*/
bool try_pref = !!indic_plan->mask_array[PREF];
@@ -1477,7 +1518,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
/* 3. If reph should be repositioned after the main consonant: find the
* first consonant not ligated with main, or find the first
- * consonant that is not a potential pre-base reordering Ra.
+ * consonant that is not a potential pre-base-reordering Ra.
*/
if (reph_pos == REPH_POS_AFTER_MAIN)
{
@@ -1497,8 +1538,8 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
if (reph_pos == REPH_POS_AFTER_SUB)
{
new_reph_pos = base;
- while (new_reph_pos < end &&
- !( FLAG_SAFE (info[new_reph_pos + 1].indic_position()) & (FLAG (POS_POST_C) | FLAG (POS_AFTER_POST) | FLAG (POS_SMVD))))
+ while (new_reph_pos + 1 < end &&
+ !( FLAG_UNSAFE (info[new_reph_pos + 1].indic_position()) & (FLAG (POS_POST_C) | FLAG (POS_AFTER_POST) | FLAG (POS_SMVD))))
new_reph_pos++;
if (new_reph_pos < end)
goto reph_move;
@@ -1566,13 +1607,13 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
}
- /* o Reorder pre-base reordering consonants:
+ /* o Reorder pre-base-reordering consonants:
*
- * If a pre-base reordering consonant is found, reorder it according to
+ * If a pre-base-reordering consonant is found, reorder it according to
* the following rules:
*/
- if (try_pref && base + 1 < end) /* Otherwise there can't be any pre-base reordering Ra. */
+ if (try_pref && base + 1 < end) /* Otherwise there can't be any pre-base-reordering Ra. */
{
for (unsigned int i = base + 1; i < end; i++)
if ((info[i].mask & indic_plan->mask_array[PREF]) != 0)
@@ -1646,11 +1687,15 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
/* Apply 'init' to the Left Matra if it's a word start. */
- if (info[start].indic_position () == POS_PRE_M &&
- (!start ||
- !(FLAG_SAFE (_hb_glyph_info_get_general_category (&info[start - 1])) &
- FLAG_RANGE (HB_UNICODE_GENERAL_CATEGORY_FORMAT, HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK))))
- info[start].mask |= indic_plan->mask_array[INIT];
+ if (info[start].indic_position () == POS_PRE_M)
+ {
+ if (!start ||
+ !(FLAG_UNSAFE (_hb_glyph_info_get_general_category (&info[start - 1])) &
+ FLAG_RANGE (HB_UNICODE_GENERAL_CATEGORY_FORMAT, HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)))
+ info[start].mask |= indic_plan->mask_array[INIT];
+ else
+ buffer->unsafe_to_break (start - 1, start + 1);
+ }
/*
@@ -1665,8 +1710,8 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
break;
default:
- /* Uniscribe merges the entire cluster... Except for Tamil & Sinhala.
- * This means, half forms are submerged into the main consonants cluster.
+ /* Uniscribe merges the entire syllable into a single cluster... Except for Tamil & Sinhala.
+ * This means, half forms are submerged into the main consonant's cluster.
* This is unnecessary, and makes cursor positioning harder, but that's what
* Uniscribe does. */
buffer->merge_clusters (start, end);
@@ -1738,7 +1783,7 @@ decompose_indic (const hb_ot_shape_normalize_context_t *c,
#endif
}
- if ((ab == 0x0DDAu || hb_in_range (ab, 0x0DDCu, 0x0DDEu)))
+ if ((ab == 0x0DDAu || hb_in_range<hb_codepoint_t> (ab, 0x0DDCu, 0x0DDEu)))
{
/*
* Sinhala split matras... Let the fun begin.
@@ -1803,18 +1848,18 @@ compose_indic (const hb_ot_shape_normalize_context_t *c,
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_indic =
{
- "indic",
collect_features_indic,
override_features_indic,
data_create_indic,
data_destroy_indic,
- NULL, /* preprocess_text */
- NULL, /* postprocess_glyphs */
+ nullptr, /* preprocess_text */
+ nullptr, /* postprocess_glyphs */
HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,
decompose_indic,
compose_indic,
setup_masks_indic,
- NULL, /* disable_otl */
+ nullptr, /* disable_otl */
+ nullptr, /* reorder_marks */
HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
false, /* fallback_position */
};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.hh
index 29fdf9a1ae..ed87404305 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.hh
@@ -34,197 +34,201 @@
#line 36 "hb-ot-shape-complex-myanmar-machine.hh"
static const unsigned char _myanmar_syllable_machine_trans_keys[] = {
- 1u, 31u, 3u, 30u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u,
+ 1u, 32u, 3u, 30u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u,
3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 16u, 3u, 29u, 3u, 29u, 3u, 29u,
3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 5u, 29u, 5u, 8u,
5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u,
- 3u, 30u, 3u, 29u, 1u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u,
- 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 8u, 8u, 0
+ 3u, 30u, 3u, 29u, 1u, 32u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u,
+ 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 32u, 8u, 8u, 0
};
static const char _myanmar_syllable_machine_key_spans[] = {
- 31, 28, 25, 4, 25, 23, 21, 21,
+ 32, 28, 25, 4, 25, 23, 21, 21,
27, 27, 27, 27, 16, 27, 27, 27,
27, 27, 27, 27, 27, 27, 25, 4,
25, 23, 21, 21, 27, 27, 27, 27,
- 28, 27, 30, 27, 27, 27, 27, 27,
- 27, 27, 27, 27, 1
+ 28, 27, 32, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 32, 1
};
static const short _myanmar_syllable_machine_index_offsets[] = {
- 0, 32, 61, 87, 92, 118, 142, 164,
- 186, 214, 242, 270, 298, 315, 343, 371,
- 399, 427, 455, 483, 511, 539, 567, 593,
- 598, 624, 648, 670, 692, 720, 748, 776,
- 804, 833, 861, 892, 920, 948, 976, 1004,
- 1032, 1060, 1088, 1116, 1144
+ 0, 33, 62, 88, 93, 119, 143, 165,
+ 187, 215, 243, 271, 299, 316, 344, 372,
+ 400, 428, 456, 484, 512, 540, 568, 594,
+ 599, 625, 649, 671, 693, 721, 749, 777,
+ 805, 834, 862, 895, 923, 951, 979, 1007,
+ 1035, 1063, 1091, 1119, 1147, 1180
};
static const char _myanmar_syllable_machine_indicies[] = {
1, 1, 2, 3, 4, 4, 0, 5,
0, 6, 1, 0, 0, 0, 0, 7,
- 0, 8, 1, 0, 9, 10, 11, 12,
- 13, 14, 15, 16, 17, 18, 19, 0,
- 21, 22, 23, 23, 20, 24, 20, 25,
- 20, 20, 20, 20, 20, 20, 20, 26,
- 20, 20, 27, 28, 29, 30, 31, 32,
- 33, 34, 35, 36, 20, 23, 23, 20,
- 24, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 37, 20, 20, 20, 20, 20,
- 20, 31, 20, 20, 20, 35, 20, 23,
- 23, 20, 24, 20, 23, 23, 20, 24,
- 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 20, 20,
- 31, 20, 20, 20, 35, 20, 38, 20,
- 23, 23, 20, 24, 20, 31, 20, 20,
- 20, 20, 20, 20, 20, 39, 20, 20,
- 20, 20, 20, 20, 31, 20, 23, 23,
- 20, 24, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 39, 20, 20, 20, 20,
- 20, 20, 31, 20, 23, 23, 20, 24,
- 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 20, 20,
- 31, 20, 21, 20, 23, 23, 20, 24,
- 20, 25, 20, 20, 20, 20, 20, 20,
- 20, 40, 20, 20, 40, 20, 20, 20,
- 31, 41, 20, 20, 35, 20, 21, 20,
- 23, 23, 20, 24, 20, 25, 20, 20,
- 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 31, 20, 20, 20,
- 35, 20, 21, 20, 23, 23, 20, 24,
- 20, 25, 20, 20, 20, 20, 20, 20,
- 20, 40, 20, 20, 20, 20, 20, 20,
- 31, 41, 20, 20, 35, 20, 21, 20,
- 23, 23, 20, 24, 20, 25, 20, 20,
- 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 31, 41, 20, 20,
- 35, 20, 1, 1, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 1, 20, 21, 20, 23, 23, 20,
- 24, 20, 25, 20, 20, 20, 20, 20,
- 20, 20, 26, 20, 20, 27, 28, 29,
- 30, 31, 32, 33, 34, 35, 20, 21,
- 20, 23, 23, 20, 24, 20, 25, 20,
- 20, 20, 20, 20, 20, 20, 34, 20,
- 20, 20, 20, 20, 20, 31, 32, 33,
- 34, 35, 20, 21, 20, 23, 23, 20,
- 24, 20, 25, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 31, 32, 33, 34, 35, 20, 21,
- 20, 23, 23, 20, 24, 20, 25, 20,
- 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 31, 32, 33,
- 20, 35, 20, 21, 20, 23, 23, 20,
- 24, 20, 25, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 31, 20, 33, 20, 35, 20, 21,
- 20, 23, 23, 20, 24, 20, 25, 20,
- 20, 20, 20, 20, 20, 20, 34, 20,
- 20, 27, 20, 29, 20, 31, 32, 33,
- 34, 35, 20, 21, 20, 23, 23, 20,
- 24, 20, 25, 20, 20, 20, 20, 20,
- 20, 20, 34, 20, 20, 27, 20, 20,
- 20, 31, 32, 33, 34, 35, 20, 21,
- 20, 23, 23, 20, 24, 20, 25, 20,
- 20, 20, 20, 20, 20, 20, 34, 20,
- 20, 27, 28, 29, 20, 31, 32, 33,
- 34, 35, 20, 21, 22, 23, 23, 20,
- 24, 20, 25, 20, 20, 20, 20, 20,
- 20, 20, 26, 20, 20, 27, 28, 29,
- 30, 31, 32, 33, 34, 35, 20, 3,
- 3, 42, 5, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 43, 42, 42, 42,
- 42, 42, 42, 13, 42, 42, 42, 17,
- 42, 3, 3, 42, 5, 42, 3, 3,
- 42, 5, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 13, 42, 42, 42, 17, 42,
- 44, 42, 3, 3, 42, 5, 42, 13,
- 42, 42, 42, 42, 42, 42, 42, 45,
- 42, 42, 42, 42, 42, 42, 13, 42,
- 3, 3, 42, 5, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 45, 42, 42,
- 42, 42, 42, 42, 13, 42, 3, 3,
- 42, 5, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 13, 42, 2, 42, 3, 3,
- 42, 5, 42, 6, 42, 42, 42, 42,
- 42, 42, 42, 46, 42, 42, 46, 42,
- 42, 42, 13, 47, 42, 42, 17, 42,
- 2, 42, 3, 3, 42, 5, 42, 6,
- 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 13, 42,
- 42, 42, 17, 42, 2, 42, 3, 3,
- 42, 5, 42, 6, 42, 42, 42, 42,
- 42, 42, 42, 46, 42, 42, 42, 42,
- 42, 42, 13, 47, 42, 42, 17, 42,
- 2, 42, 3, 3, 42, 5, 42, 6,
- 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 13, 47,
- 42, 42, 17, 42, 21, 22, 23, 23,
- 20, 24, 20, 25, 20, 20, 20, 20,
- 20, 20, 20, 48, 20, 20, 27, 28,
+ 0, 8, 9, 0, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 1,
+ 0, 22, 23, 24, 24, 21, 25, 21,
+ 26, 21, 21, 21, 21, 21, 21, 21,
+ 27, 21, 21, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 21, 24, 24,
+ 21, 25, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 38, 21, 21, 21, 21,
+ 21, 21, 32, 21, 21, 21, 36, 21,
+ 24, 24, 21, 25, 21, 24, 24, 21,
+ 25, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 32, 21, 21, 21, 36, 21, 39,
+ 21, 24, 24, 21, 25, 21, 32, 21,
+ 21, 21, 21, 21, 21, 21, 40, 21,
+ 21, 21, 21, 21, 21, 32, 21, 24,
+ 24, 21, 25, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 40, 21, 21, 21,
+ 21, 21, 21, 32, 21, 24, 24, 21,
+ 25, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 32, 21, 22, 21, 24, 24, 21,
+ 25, 21, 26, 21, 21, 21, 21, 21,
+ 21, 21, 41, 21, 21, 41, 21, 21,
+ 21, 32, 42, 21, 21, 36, 21, 22,
+ 21, 24, 24, 21, 25, 21, 26, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 32, 21, 21,
+ 21, 36, 21, 22, 21, 24, 24, 21,
+ 25, 21, 26, 21, 21, 21, 21, 21,
+ 21, 21, 41, 21, 21, 21, 21, 21,
+ 21, 32, 42, 21, 21, 36, 21, 22,
+ 21, 24, 24, 21, 25, 21, 26, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 32, 42, 21,
+ 21, 36, 21, 1, 1, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 1, 21, 22, 21, 24, 24,
+ 21, 25, 21, 26, 21, 21, 21, 21,
+ 21, 21, 21, 27, 21, 21, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 21,
+ 22, 21, 24, 24, 21, 25, 21, 26,
+ 21, 21, 21, 21, 21, 21, 21, 35,
+ 21, 21, 21, 21, 21, 21, 32, 33,
+ 34, 35, 36, 21, 22, 21, 24, 24,
+ 21, 25, 21, 26, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 32, 33, 34, 35, 36, 21,
+ 22, 21, 24, 24, 21, 25, 21, 26,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 32, 33,
+ 34, 21, 36, 21, 22, 21, 24, 24,
+ 21, 25, 21, 26, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 32, 21, 34, 21, 36, 21,
+ 22, 21, 24, 24, 21, 25, 21, 26,
+ 21, 21, 21, 21, 21, 21, 21, 35,
+ 21, 21, 28, 21, 30, 21, 32, 33,
+ 34, 35, 36, 21, 22, 21, 24, 24,
+ 21, 25, 21, 26, 21, 21, 21, 21,
+ 21, 21, 21, 35, 21, 21, 28, 21,
+ 21, 21, 32, 33, 34, 35, 36, 21,
+ 22, 21, 24, 24, 21, 25, 21, 26,
+ 21, 21, 21, 21, 21, 21, 21, 35,
+ 21, 21, 28, 29, 30, 21, 32, 33,
+ 34, 35, 36, 21, 22, 23, 24, 24,
+ 21, 25, 21, 26, 21, 21, 21, 21,
+ 21, 21, 21, 27, 21, 21, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 21,
+ 3, 3, 43, 5, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 44, 43, 43,
+ 43, 43, 43, 43, 14, 43, 43, 43,
+ 18, 43, 3, 3, 43, 5, 43, 3,
+ 3, 43, 5, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 14, 43, 43, 43, 18,
+ 43, 45, 43, 3, 3, 43, 5, 43,
+ 14, 43, 43, 43, 43, 43, 43, 43,
+ 46, 43, 43, 43, 43, 43, 43, 14,
+ 43, 3, 3, 43, 5, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 46, 43,
+ 43, 43, 43, 43, 43, 14, 43, 3,
+ 3, 43, 5, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 14, 43, 2, 43, 3,
+ 3, 43, 5, 43, 6, 43, 43, 43,
+ 43, 43, 43, 43, 47, 43, 43, 47,
+ 43, 43, 43, 14, 48, 43, 43, 18,
+ 43, 2, 43, 3, 3, 43, 5, 43,
+ 6, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 14,
+ 43, 43, 43, 18, 43, 2, 43, 3,
+ 3, 43, 5, 43, 6, 43, 43, 43,
+ 43, 43, 43, 43, 47, 43, 43, 43,
+ 43, 43, 43, 14, 48, 43, 43, 18,
+ 43, 2, 43, 3, 3, 43, 5, 43,
+ 6, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 14,
+ 48, 43, 43, 18, 43, 22, 23, 24,
+ 24, 21, 25, 21, 26, 21, 21, 21,
+ 21, 21, 21, 21, 49, 21, 21, 28,
29, 30, 31, 32, 33, 34, 35, 36,
- 20, 21, 49, 23, 23, 20, 24, 20,
- 25, 20, 20, 20, 20, 20, 20, 20,
- 26, 20, 20, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 20, 1, 1, 2,
- 3, 3, 3, 42, 5, 42, 6, 1,
- 42, 42, 42, 42, 1, 42, 8, 1,
- 42, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 42, 2, 42, 3, 3,
- 42, 5, 42, 6, 42, 42, 42, 42,
- 42, 42, 42, 8, 42, 42, 9, 10,
- 11, 12, 13, 14, 15, 16, 17, 42,
- 2, 42, 3, 3, 42, 5, 42, 6,
- 42, 42, 42, 42, 42, 42, 42, 16,
- 42, 42, 42, 42, 42, 42, 13, 14,
- 15, 16, 17, 42, 2, 42, 3, 3,
- 42, 5, 42, 6, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 13, 14, 15, 16, 17, 42,
- 2, 42, 3, 3, 42, 5, 42, 6,
- 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 13, 14,
- 15, 42, 17, 42, 2, 42, 3, 3,
- 42, 5, 42, 6, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 13, 42, 15, 42, 17, 42,
- 2, 42, 3, 3, 42, 5, 42, 6,
- 42, 42, 42, 42, 42, 42, 42, 16,
- 42, 42, 9, 42, 11, 42, 13, 14,
- 15, 16, 17, 42, 2, 42, 3, 3,
- 42, 5, 42, 6, 42, 42, 42, 42,
- 42, 42, 42, 16, 42, 42, 9, 42,
- 42, 42, 13, 14, 15, 16, 17, 42,
- 2, 42, 3, 3, 42, 5, 42, 6,
- 42, 42, 42, 42, 42, 42, 42, 16,
- 42, 42, 9, 10, 11, 42, 13, 14,
- 15, 16, 17, 42, 2, 3, 3, 3,
- 42, 5, 42, 6, 42, 42, 42, 42,
- 42, 42, 42, 8, 42, 42, 9, 10,
- 11, 12, 13, 14, 15, 16, 17, 42,
- 51, 50, 0
+ 37, 21, 22, 50, 24, 24, 21, 25,
+ 21, 26, 21, 21, 21, 21, 21, 21,
+ 21, 27, 21, 21, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 21, 1, 1,
+ 2, 3, 3, 3, 43, 5, 43, 6,
+ 1, 43, 43, 43, 43, 1, 43, 8,
+ 43, 43, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 43, 1, 43, 2,
+ 43, 3, 3, 43, 5, 43, 6, 43,
+ 43, 43, 43, 43, 43, 43, 8, 43,
+ 43, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 43, 2, 43, 3, 3, 43,
+ 5, 43, 6, 43, 43, 43, 43, 43,
+ 43, 43, 17, 43, 43, 43, 43, 43,
+ 43, 14, 15, 16, 17, 18, 43, 2,
+ 43, 3, 3, 43, 5, 43, 6, 43,
+ 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 14, 15, 16,
+ 17, 18, 43, 2, 43, 3, 3, 43,
+ 5, 43, 6, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 14, 15, 16, 43, 18, 43, 2,
+ 43, 3, 3, 43, 5, 43, 6, 43,
+ 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 14, 43, 16,
+ 43, 18, 43, 2, 43, 3, 3, 43,
+ 5, 43, 6, 43, 43, 43, 43, 43,
+ 43, 43, 17, 43, 43, 10, 43, 12,
+ 43, 14, 15, 16, 17, 18, 43, 2,
+ 43, 3, 3, 43, 5, 43, 6, 43,
+ 43, 43, 43, 43, 43, 43, 17, 43,
+ 43, 10, 43, 43, 43, 14, 15, 16,
+ 17, 18, 43, 2, 43, 3, 3, 43,
+ 5, 43, 6, 43, 43, 43, 43, 43,
+ 43, 43, 17, 43, 43, 10, 11, 12,
+ 43, 14, 15, 16, 17, 18, 43, 2,
+ 3, 3, 3, 43, 5, 43, 6, 43,
+ 43, 43, 43, 43, 43, 43, 8, 43,
+ 43, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 43, 1, 1, 51, 51, 51,
+ 51, 51, 51, 51, 51, 1, 51, 51,
+ 51, 51, 1, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 1, 51, 52, 51, 0
};
static const char _myanmar_syllable_machine_trans_targs[] = {
0, 1, 22, 0, 0, 23, 29, 32,
- 35, 36, 40, 41, 42, 25, 38, 39,
- 37, 28, 43, 44, 0, 2, 12, 0,
- 3, 9, 13, 14, 18, 19, 20, 5,
- 16, 17, 15, 8, 21, 4, 6, 7,
- 10, 11, 0, 24, 26, 27, 30, 31,
- 33, 34, 0, 0
+ 35, 44, 36, 40, 41, 42, 25, 38,
+ 39, 37, 28, 43, 45, 0, 2, 12,
+ 0, 3, 9, 13, 14, 18, 19, 20,
+ 5, 16, 17, 15, 8, 21, 4, 6,
+ 7, 10, 11, 0, 24, 26, 27, 30,
+ 31, 33, 34, 0, 0
};
static const char _myanmar_syllable_machine_trans_actions[] = {
3, 0, 0, 4, 5, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 6, 0, 0, 7,
- 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 6, 0, 0,
+ 7, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 8, 0, 0, 0, 0, 0,
- 0, 0, 9, 10
+ 0, 0, 0, 8, 0, 0, 0, 0,
+ 0, 0, 0, 9, 10
};
static const char _myanmar_syllable_machine_to_state_actions[] = {
@@ -233,7 +237,7 @@ static const char _myanmar_syllable_machine_to_state_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0
};
static const char _myanmar_syllable_machine_from_state_actions[] = {
@@ -242,16 +246,16 @@ static const char _myanmar_syllable_machine_from_state_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0
};
static const short _myanmar_syllable_machine_eof_trans[] = {
- 0, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 43,
- 21, 21, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 51
+ 0, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 44, 44,
+ 44, 44, 44, 44, 44, 44, 44, 44,
+ 22, 22, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 44, 52, 52
};
static const int myanmar_syllable_machine_start = 0;
@@ -265,7 +269,7 @@ static const int myanmar_syllable_machine_en_main = 0;
-#line 93 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 94 "hb-ot-shape-complex-myanmar-machine.rl"
#define found_syllable(syllable_type) \
@@ -285,7 +289,7 @@ find_syllables (hb_buffer_t *buffer)
int cs;
hb_glyph_info_t *info = buffer->info;
-#line 289 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 293 "hb-ot-shape-complex-myanmar-machine.hh"
{
cs = myanmar_syllable_machine_start;
ts = 0;
@@ -293,7 +297,7 @@ find_syllables (hb_buffer_t *buffer)
act = 0;
}
-#line 114 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 115 "hb-ot-shape-complex-myanmar-machine.rl"
p = 0;
@@ -302,7 +306,7 @@ find_syllables (hb_buffer_t *buffer)
unsigned int last = 0;
unsigned int syllable_serial = 1;
-#line 306 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 310 "hb-ot-shape-complex-myanmar-machine.hh"
{
int _slen;
int _trans;
@@ -316,7 +320,7 @@ _resume:
#line 1 "NONE"
{ts = p;}
break;
-#line 320 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 324 "hb-ot-shape-complex-myanmar-machine.hh"
}
_keys = _myanmar_syllable_machine_trans_keys + (cs<<1);
@@ -335,38 +339,38 @@ _eof_trans:
switch ( _myanmar_syllable_machine_trans_actions[_trans] ) {
case 7:
-#line 85 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 86 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (consonant_syllable); }}
break;
case 5:
-#line 86 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 87 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (non_myanmar_cluster); }}
break;
case 10:
-#line 87 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 88 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (punctuation_cluster); }}
break;
case 4:
-#line 88 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (broken_cluster); }}
break;
case 3:
-#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 90 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (non_myanmar_cluster); }}
break;
case 6:
-#line 85 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 86 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p;p--;{ found_syllable (consonant_syllable); }}
break;
case 8:
-#line 88 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p;p--;{ found_syllable (broken_cluster); }}
break;
case 9:
-#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 90 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p;p--;{ found_syllable (non_myanmar_cluster); }}
break;
-#line 370 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 374 "hb-ot-shape-complex-myanmar-machine.hh"
}
_again:
@@ -375,7 +379,7 @@ _again:
#line 1 "NONE"
{ts = 0;}
break;
-#line 379 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 383 "hb-ot-shape-complex-myanmar-machine.hh"
}
if ( ++p != pe )
@@ -391,7 +395,7 @@ _again:
}
-#line 123 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 124 "hb-ot-shape-complex-myanmar-machine.rl"
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc
index bb68622e2a..5ea1dbff27 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc
@@ -103,7 +103,7 @@ collect_features_myanmar (hb_ot_shape_planner_t *plan)
for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++)
{
map->add_feature (basic_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ);
- map->add_gsub_pause (NULL);
+ map->add_gsub_pause (nullptr);
}
map->add_gsub_pause (final_reordering);
for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++)
@@ -130,8 +130,7 @@ enum syllable_type_t {
/* Note: This enum is duplicated in the -machine.rl source file.
* Not sure how to avoid duplication. */
enum myanmar_category_t {
- OT_As = 18, /* Asat */
- OT_D = 19, /* Digits except zero */
+ OT_As = 18, /* Asat */
OT_D0 = 20, /* Digit zero */
OT_DB = OT_N, /* Dot below */
OT_GB = OT_PLACEHOLDER,
@@ -145,7 +144,8 @@ enum myanmar_category_t {
OT_VPre = 28,
OT_VPst = 29,
OT_VS = 30, /* Variation selectors */
- OT_P = 31 /* Punctuation */
+ OT_P = 31, /* Punctuation */
+ OT_D = 32, /* Digits except zero */
};
@@ -154,7 +154,7 @@ is_one_of (const hb_glyph_info_t &info, unsigned int flags)
{
/* If it ligated, all bets are off. */
if (_hb_glyph_info_ligated (&info)) return false;
- return !!(FLAG_SAFE (info.myanmar_category()) & flags);
+ return !!(FLAG_UNSAFE (info.myanmar_category()) & flags);
}
static inline bool
@@ -175,7 +175,7 @@ set_myanmar_properties (hb_glyph_info_t &info)
/* Myanmar
* http://www.microsoft.com/typography/OpenTypeDev/myanmar/intro.htm#analyze
*/
- if (unlikely (hb_in_range (u, 0xFE00u, 0xFE0Fu)))
+ if (unlikely (hb_in_range<hb_codepoint_t> (u, 0xFE00u, 0xFE0Fu)))
cat = (indic_category_t) OT_VS;
switch (u)
@@ -297,6 +297,8 @@ setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_buffer_t *buffer)
{
find_syllables (buffer);
+ foreach_syllable (buffer, start, end)
+ buffer->unsafe_to_break (start, end);
}
static int
@@ -510,36 +512,36 @@ final_reordering (const hb_ot_shape_plan_t *plan,
* generic shaper, except that it zeros mark advances GDEF_LATE. */
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar_old =
{
- "default",
- NULL, /* collect_features */
- NULL, /* override_features */
- NULL, /* data_create */
- NULL, /* data_destroy */
- NULL, /* preprocess_text */
- NULL, /* postprocess_glyphs */
+ nullptr, /* collect_features */
+ nullptr, /* override_features */
+ nullptr, /* data_create */
+ nullptr, /* data_destroy */
+ nullptr, /* preprocess_text */
+ nullptr, /* postprocess_glyphs */
HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
- NULL, /* decompose */
- NULL, /* compose */
- NULL, /* setup_masks */
- NULL, /* disable_otl */
+ nullptr, /* decompose */
+ nullptr, /* compose */
+ nullptr, /* setup_masks */
+ nullptr, /* disable_otl */
+ nullptr, /* reorder_marks */
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
true, /* fallback_position */
};
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar =
{
- "myanmar",
collect_features_myanmar,
override_features_myanmar,
- NULL, /* data_create */
- NULL, /* data_destroy */
- NULL, /* preprocess_text */
- NULL, /* postprocess_glyphs */
+ nullptr, /* data_create */
+ nullptr, /* data_destroy */
+ nullptr, /* preprocess_text */
+ nullptr, /* postprocess_glyphs */
HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,
- NULL, /* decompose */
- NULL, /* compose */
+ nullptr, /* decompose */
+ nullptr, /* compose */
setup_masks_myanmar,
- NULL, /* disable_otl */
+ nullptr, /* disable_otl */
+ nullptr, /* reorder_marks */
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY,
false, /* fallback_position */
};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh
index 39572dfe00..fb2f61157a 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh
@@ -39,6 +39,8 @@
#define complex_var_u8_1() var2.u8[3]
+#define HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS 32
+
enum hb_ot_shape_zero_width_marks_type_t {
HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY,
@@ -63,12 +65,10 @@ enum hb_ot_shape_zero_width_marks_type_t {
struct hb_ot_complex_shaper_t
{
- char name[8];
-
/* collect_features()
* Called during shape_plan().
* Shapers should use plan->map to add their features and callbacks.
- * May be NULL.
+ * May be nullptr.
*/
void (*collect_features) (hb_ot_shape_planner_t *plan);
@@ -76,7 +76,7 @@ struct hb_ot_complex_shaper_t
* Called during shape_plan().
* Shapers should use plan->map to override features and add callbacks after
* common features are added.
- * May be NULL.
+ * May be nullptr.
*/
void (*override_features) (hb_ot_shape_planner_t *plan);
@@ -84,15 +84,15 @@ struct hb_ot_complex_shaper_t
/* data_create()
* Called at the end of shape_plan().
* Whatever shapers return will be accessible through plan->data later.
- * If NULL is returned, means a plan failure.
+ * If nullptr is returned, means a plan failure.
*/
void *(*data_create) (const hb_ot_shape_plan_t *plan);
/* data_destroy()
* Called when the shape_plan is being destroyed.
* plan->data is passed here for destruction.
- * If NULL is returned, means a plan failure.
- * May be NULL.
+ * If nullptr is returned, means a plan failure.
+ * May be nullptr.
*/
void (*data_destroy) (void *data);
@@ -100,7 +100,7 @@ struct hb_ot_complex_shaper_t
/* preprocess_text()
* Called during shape().
* Shapers can use to modify text before shaping starts.
- * May be NULL.
+ * May be nullptr.
*/
void (*preprocess_text) (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
@@ -109,7 +109,7 @@ struct hb_ot_complex_shaper_t
/* postprocess_glyphs()
* Called during shape().
* Shapers can use to modify glyphs after shaping ends.
- * May be NULL.
+ * May be nullptr.
*/
void (*postprocess_glyphs) (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
@@ -120,7 +120,7 @@ struct hb_ot_complex_shaper_t
/* decompose()
* Called during shape()'s normalization.
- * May be NULL.
+ * May be nullptr.
*/
bool (*decompose) (const hb_ot_shape_normalize_context_t *c,
hb_codepoint_t ab,
@@ -129,7 +129,7 @@ struct hb_ot_complex_shaper_t
/* compose()
* Called during shape()'s normalization.
- * May be NULL.
+ * May be nullptr.
*/
bool (*compose) (const hb_ot_shape_normalize_context_t *c,
hb_codepoint_t a,
@@ -140,7 +140,7 @@ struct hb_ot_complex_shaper_t
* Called during shape().
* Shapers should use map to get feature masks and set on buffer.
* Shapers may NOT modify characters.
- * May be NULL.
+ * May be nullptr.
*/
void (*setup_masks) (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
@@ -150,10 +150,20 @@ struct hb_ot_complex_shaper_t
* Called during shape().
* If set and returns true, GDEF/GSUB/GPOS of the font are ignored
* and fallback operations used.
- * May be NULL.
+ * May be nullptr.
*/
bool (*disable_otl) (const hb_ot_shape_plan_t *plan);
+ /* reorder_marks()
+ * Called during shape().
+ * Shapers can use to modify ordering of combining marks.
+ * May be nullptr.
+ */
+ void (*reorder_marks) (const hb_ot_shape_plan_t *plan,
+ hb_buffer_t *buffer,
+ unsigned int start,
+ unsigned int end);
+
hb_ot_shape_zero_width_marks_type_t zero_width_marks;
bool fallback_position;
@@ -191,6 +201,9 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
case HB_SCRIPT_MANICHAEAN:
case HB_SCRIPT_PSALTER_PAHLAVI:
+ /* Unicode-9.0 additions */
+ case HB_SCRIPT_ADLAM:
+
/* For Arabic script, use the Arabic shaper even if no OT script tag was found.
* This is because we do fallback shaping for Arabic script (and not others).
* But note that Arabic shaping is applicable only to horizontal layout; for
@@ -250,10 +263,12 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
case HB_SCRIPT_SINHALA:
/* If the designer designed the font for the 'DFLT' script,
- * use the default shaper. Otherwise, use the specific shaper.
+ * (or we ended up arbitrarily pick 'latn'), use the default shaper.
+ * Otherwise, use the specific shaper.
* Note that for some simple scripts, there may not be *any*
* GSUB/GPOS needed, so there may be no scripts found! */
- if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T'))
+ if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T') ||
+ planner->map.chosen_script[0] == HB_TAG ('l','a','t','n'))
return &_hb_ot_complex_shaper_default;
else
return &_hb_ot_complex_shaper_indic;
@@ -269,7 +284,7 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
planner->map.script_index[0],
planner->map.language_index[0],
HB_TAG ('p','r','e','f'),
- NULL))
+ nullptr))
return &_hb_ot_complex_shaper_indic;
else
return &_hb_ot_complex_shaper_default;
@@ -359,11 +374,18 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
case HB_SCRIPT_MARCHEN:
case HB_SCRIPT_NEWA:
+ /* Unicode-10.0 additions */
+ case HB_SCRIPT_MASARAM_GONDI:
+ case HB_SCRIPT_SOYOMBO:
+ case HB_SCRIPT_ZANABAZAR_SQUARE:
+
/* If the designer designed the font for the 'DFLT' script,
- * use the default shaper. Otherwise, use the specific shaper.
+ * (or we ended up arbitrarily pick 'latn'), use the default shaper.
+ * Otherwise, use the specific shaper.
* Note that for some simple scripts, there may not be *any*
* GSUB/GPOS needed, so there may be no scripts found! */
- if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T'))
+ if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T') ||
+ planner->map.chosen_script[0] == HB_TAG ('l','a','t','n'))
return &_hb_ot_complex_shaper_default;
else
return &_hb_ot_complex_shaper_use;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc
index e6f80f59e7..6ba925c675 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc
@@ -52,7 +52,7 @@ get_consonant_type (hb_codepoint_t u)
return RC;
if (u == 0x0E0Eu || u == 0x0E0Fu)
return DC;
- if (hb_in_range (u, 0x0E01u, 0x0E2Eu))
+ if (hb_in_range<hb_codepoint_t> (u, 0x0E01u, 0x0E2Eu))
return NC;
return NOT_CONSONANT;
}
@@ -70,12 +70,12 @@ enum thai_mark_type_t
static thai_mark_type_t
get_mark_type (hb_codepoint_t u)
{
- if (u == 0x0E31u || hb_in_range (u, 0x0E34u, 0x0E37u) ||
- u == 0x0E47u || hb_in_range (u, 0x0E4Du, 0x0E4Eu))
+ if (u == 0x0E31u || hb_in_range<hb_codepoint_t> (u, 0x0E34u, 0x0E37u) ||
+ u == 0x0E47u || hb_in_range<hb_codepoint_t> (u, 0x0E4Du, 0x0E4Eu))
return AV;
- if (hb_in_range (u, 0x0E38u, 0x0E3Au))
+ if (hb_in_range<hb_codepoint_t> (u, 0x0E38u, 0x0E3Au))
return BV;
- if (hb_in_range (u, 0x0E48u, 0x0E4Cu))
+ if (hb_in_range<hb_codepoint_t> (u, 0x0E48u, 0x0E4Cu))
return T;
return NOT_MARK;
}
@@ -97,7 +97,7 @@ thai_pua_shape (hb_codepoint_t u, thai_action_t action, hb_font_t *font)
hb_codepoint_t u;
hb_codepoint_t win_pua;
hb_codepoint_t mac_pua;
- } const *pua_mappings = NULL;
+ } const *pua_mappings = nullptr;
static const thai_pua_mapping_t SD_mappings[] = {
{0x0E48u, 0xF70Au, 0xF88Bu}, /* MAI EK */
{0x0E49u, 0xF70Bu, 0xF88Eu}, /* MAI THO */
@@ -244,6 +244,7 @@ do_thai_pua_shaping (const hb_ot_shape_plan_t *plan HB_UNUSED,
/* At least one of the above/below actions is NOP. */
thai_action_t action = above_edge.action != NOP ? above_edge.action : below_edge.action;
+ buffer->unsafe_to_break (base, i);
if (action == RD)
info[base].codepoint = thai_pua_shape (info[base].codepoint, action, font);
else
@@ -310,7 +311,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan,
#define IS_SARA_AM(x) (((x) & ~0x0080u) == 0x0E33u)
#define NIKHAHIT_FROM_SARA_AM(x) ((x) - 0x0E33u + 0x0E4Du)
#define SARA_AA_FROM_SARA_AM(x) ((x) - 1)
-#define IS_TONE_MARK(x) (hb_in_ranges ((x) & ~0x0080u, 0x0E34u, 0x0E37u, 0x0E47u, 0x0E4Eu, 0x0E31u, 0x0E31u))
+#define IS_TONE_MARK(x) (hb_in_ranges<hb_codepoint_t> ((x) & ~0x0080u, 0x0E34u, 0x0E37u, 0x0E47u, 0x0E4Eu, 0x0E31u, 0x0E31u))
buffer->clear_output ();
unsigned int count = buffer->len;
@@ -365,18 +366,18 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan,
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_thai =
{
- "thai",
- NULL, /* collect_features */
- NULL, /* override_features */
- NULL, /* data_create */
- NULL, /* data_destroy */
+ nullptr, /* collect_features */
+ nullptr, /* override_features */
+ nullptr, /* data_create */
+ nullptr, /* data_destroy */
preprocess_text_thai,
- NULL, /* postprocess_glyphs */
+ nullptr, /* postprocess_glyphs */
HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
- NULL, /* decompose */
- NULL, /* compose */
- NULL, /* setup_masks */
- NULL, /* disable_otl */
+ nullptr, /* decompose */
+ nullptr, /* compose */
+ nullptr, /* setup_masks */
+ nullptr, /* disable_otl */
+ nullptr, /* reorder_marks */
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
false,/* fallback_position */
};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-tibetan.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-tibetan.cc
index aadf59f5ad..eaac0bf689 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-tibetan.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-tibetan.cc
@@ -46,18 +46,18 @@ collect_features_tibetan (hb_ot_shape_planner_t *plan)
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_tibetan =
{
- "default",
collect_features_tibetan,
- NULL, /* override_features */
- NULL, /* data_create */
- NULL, /* data_destroy */
- NULL, /* preprocess_text */
- NULL, /* postprocess_glyphs */
+ nullptr, /* override_features */
+ nullptr, /* data_create */
+ nullptr, /* data_destroy */
+ nullptr, /* preprocess_text */
+ nullptr, /* postprocess_glyphs */
HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
- NULL, /* decompose */
- NULL, /* compose */
- NULL, /* setup_masks */
- NULL, /* disable_otl */
+ nullptr, /* decompose */
+ nullptr, /* compose */
+ nullptr, /* setup_masks */
+ nullptr, /* disable_otl */
+ nullptr, /* reorder_marks */
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
true, /* fallback_position */
};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-machine.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-machine.hh
index 44e5d0d56b..4f6727186d 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-machine.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-machine.hh
@@ -36,33 +36,33 @@
#line 38 "hb-ot-shape-complex-use-machine.hh"
static const unsigned char _use_syllable_machine_trans_keys[] = {
- 1u, 1u, 0u, 39u, 21u, 21u, 8u, 39u, 8u, 39u, 1u, 1u, 8u, 39u, 8u, 39u,
+ 1u, 1u, 0u, 43u, 21u, 21u, 8u, 39u, 8u, 39u, 1u, 1u, 8u, 39u, 8u, 39u,
8u, 39u, 8u, 26u, 8u, 26u, 8u, 26u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u,
- 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 13u, 21u,
- 4u, 4u, 13u, 13u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 26u, 8u, 26u,
- 8u, 26u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u,
- 8u, 39u, 8u, 39u, 8u, 39u, 1u, 1u, 1u, 39u, 8u, 39u, 21u, 42u, 41u, 42u,
- 42u, 42u, 0
+ 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u,
+ 13u, 21u, 4u, 4u, 13u, 13u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 26u,
+ 8u, 26u, 8u, 26u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u,
+ 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 1u, 1u, 1u, 39u, 8u, 39u,
+ 21u, 42u, 41u, 42u, 42u, 42u, 1u, 5u, 0
};
static const char _use_syllable_machine_key_spans[] = {
- 1, 40, 1, 32, 32, 1, 32, 32,
+ 1, 44, 1, 32, 32, 1, 32, 32,
32, 19, 19, 19, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 9,
- 1, 1, 32, 32, 32, 32, 19, 19,
- 19, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 1, 39, 32, 22, 2,
- 1
+ 32, 32, 32, 32, 32, 32, 32, 32,
+ 9, 1, 1, 32, 32, 32, 32, 19,
+ 19, 19, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 1, 39, 32,
+ 22, 2, 1, 5
};
static const short _use_syllable_machine_index_offsets[] = {
- 0, 2, 43, 45, 78, 111, 113, 146,
- 179, 212, 232, 252, 272, 305, 338, 371,
- 404, 437, 470, 503, 536, 569, 602, 635,
- 645, 647, 649, 682, 715, 748, 781, 801,
- 821, 841, 874, 907, 940, 973, 1006, 1039,
- 1072, 1105, 1138, 1171, 1173, 1213, 1246, 1269,
- 1272
+ 0, 2, 47, 49, 82, 115, 117, 150,
+ 183, 216, 236, 256, 276, 309, 342, 375,
+ 408, 441, 474, 507, 540, 573, 606, 639,
+ 672, 682, 684, 686, 719, 752, 785, 818,
+ 838, 858, 878, 911, 944, 977, 1010, 1043,
+ 1076, 1109, 1142, 1175, 1208, 1241, 1243, 1283,
+ 1316, 1339, 1342, 1344
};
static const char _use_syllable_machine_indicies[] = {
@@ -71,183 +71,192 @@ static const char _use_syllable_machine_indicies[] = {
4, 4, 2, 2, 8, 9, 4, 4,
10, 11, 12, 13, 14, 15, 16, 10,
17, 18, 19, 20, 21, 22, 4, 23,
- 24, 25, 4, 27, 26, 29, 28, 28,
- 30, 31, 28, 28, 28, 28, 28, 28,
- 28, 28, 32, 33, 34, 35, 36, 37,
- 38, 39, 33, 40, 32, 41, 42, 43,
- 44, 28, 45, 46, 47, 28, 29, 28,
- 28, 30, 31, 28, 28, 28, 28, 28,
- 28, 28, 28, 48, 33, 34, 35, 36,
- 37, 38, 39, 33, 40, 41, 41, 42,
- 43, 44, 28, 45, 46, 47, 28, 30,
- 49, 29, 28, 28, 30, 31, 28, 28,
- 28, 28, 28, 28, 28, 28, 28, 33,
- 34, 35, 36, 37, 38, 39, 33, 40,
- 41, 41, 42, 43, 44, 28, 45, 46,
- 47, 28, 29, 28, 28, 28, 28, 28,
- 28, 28, 28, 28, 28, 28, 28, 28,
- 33, 34, 35, 36, 37, 28, 28, 28,
- 28, 28, 28, 42, 43, 44, 28, 45,
- 46, 47, 28, 29, 28, 28, 28, 28,
- 28, 28, 28, 28, 28, 28, 28, 28,
- 28, 28, 34, 35, 36, 37, 28, 28,
- 28, 28, 28, 28, 28, 28, 28, 28,
- 45, 46, 47, 28, 29, 28, 28, 28,
- 28, 28, 28, 28, 28, 28, 28, 28,
- 28, 28, 28, 28, 35, 36, 37, 28,
- 29, 28, 28, 28, 28, 28, 28, 28,
- 28, 28, 28, 28, 28, 28, 28, 28,
- 28, 36, 37, 28, 29, 28, 28, 28,
- 28, 28, 28, 28, 28, 28, 28, 28,
- 28, 28, 28, 28, 28, 28, 37, 28,
- 29, 28, 28, 28, 28, 28, 28, 28,
- 28, 28, 28, 28, 28, 28, 28, 28,
- 35, 36, 37, 28, 28, 28, 28, 28,
- 28, 28, 28, 28, 28, 45, 46, 47,
- 28, 29, 28, 28, 28, 28, 28, 28,
- 28, 28, 28, 28, 28, 28, 28, 28,
- 28, 35, 36, 37, 28, 28, 28, 28,
- 28, 28, 28, 28, 28, 28, 28, 46,
- 47, 28, 29, 28, 28, 28, 28, 28,
- 28, 28, 28, 28, 28, 28, 28, 28,
- 28, 28, 35, 36, 37, 28, 28, 28,
- 28, 28, 28, 28, 28, 28, 28, 28,
- 28, 47, 28, 29, 28, 28, 28, 28,
- 28, 28, 28, 28, 28, 28, 28, 28,
- 28, 28, 34, 35, 36, 37, 28, 28,
- 28, 28, 28, 28, 42, 43, 44, 28,
- 45, 46, 47, 28, 29, 28, 28, 28,
- 28, 28, 28, 28, 28, 28, 28, 28,
- 28, 28, 28, 34, 35, 36, 37, 28,
- 28, 28, 28, 28, 28, 28, 43, 44,
- 28, 45, 46, 47, 28, 29, 28, 28,
- 28, 28, 28, 28, 28, 28, 28, 28,
- 28, 28, 28, 28, 34, 35, 36, 37,
- 28, 28, 28, 28, 28, 28, 28, 28,
- 44, 28, 45, 46, 47, 28, 29, 28,
- 28, 28, 28, 28, 28, 28, 28, 28,
- 28, 28, 28, 28, 33, 34, 35, 36,
- 37, 28, 39, 33, 28, 28, 28, 42,
- 43, 44, 28, 45, 46, 47, 28, 29,
- 28, 28, 28, 28, 28, 28, 28, 28,
- 28, 28, 28, 28, 28, 33, 34, 35,
- 36, 37, 28, 28, 33, 28, 28, 28,
- 42, 43, 44, 28, 45, 46, 47, 28,
- 29, 28, 28, 28, 28, 28, 28, 28,
- 28, 28, 28, 28, 28, 28, 33, 34,
- 35, 36, 37, 38, 39, 33, 28, 28,
- 28, 42, 43, 44, 28, 45, 46, 47,
- 28, 29, 28, 28, 30, 31, 28, 28,
- 28, 28, 28, 28, 28, 28, 28, 33,
- 34, 35, 36, 37, 38, 39, 33, 40,
- 28, 41, 42, 43, 44, 28, 45, 46,
- 47, 28, 29, 28, 28, 30, 31, 28,
- 28, 28, 28, 28, 28, 28, 28, 28,
- 33, 34, 35, 36, 37, 38, 39, 33,
- 40, 32, 41, 42, 43, 44, 28, 45,
- 46, 47, 28, 51, 50, 50, 50, 50,
- 50, 50, 50, 52, 50, 5, 53, 51,
- 50, 6, 54, 54, 1, 55, 54, 54,
- 54, 54, 54, 54, 54, 54, 56, 10,
- 11, 12, 13, 14, 15, 16, 10, 17,
- 19, 19, 20, 21, 22, 54, 23, 24,
- 25, 54, 6, 54, 54, 1, 55, 54,
- 54, 54, 54, 54, 54, 54, 54, 54,
- 10, 11, 12, 13, 14, 15, 16, 10,
- 17, 19, 19, 20, 21, 22, 54, 23,
- 24, 25, 54, 6, 54, 54, 54, 54,
- 54, 54, 54, 54, 54, 54, 54, 54,
- 54, 10, 11, 12, 13, 14, 54, 54,
- 54, 54, 54, 54, 20, 21, 22, 54,
- 23, 24, 25, 54, 6, 54, 54, 54,
- 54, 54, 54, 54, 54, 54, 54, 54,
- 54, 54, 54, 11, 12, 13, 14, 54,
- 54, 54, 54, 54, 54, 54, 54, 54,
- 54, 23, 24, 25, 54, 6, 54, 54,
- 54, 54, 54, 54, 54, 54, 54, 54,
- 54, 54, 54, 54, 54, 12, 13, 14,
- 54, 6, 54, 54, 54, 54, 54, 54,
- 54, 54, 54, 54, 54, 54, 54, 54,
- 54, 54, 13, 14, 54, 6, 54, 54,
- 54, 54, 54, 54, 54, 54, 54, 54,
- 54, 54, 54, 54, 54, 54, 54, 14,
- 54, 6, 54, 54, 54, 54, 54, 54,
- 54, 54, 54, 54, 54, 54, 54, 54,
- 54, 12, 13, 14, 54, 54, 54, 54,
- 54, 54, 54, 54, 54, 54, 23, 24,
- 25, 54, 6, 54, 54, 54, 54, 54,
- 54, 54, 54, 54, 54, 54, 54, 54,
- 54, 54, 12, 13, 14, 54, 54, 54,
- 54, 54, 54, 54, 54, 54, 54, 54,
- 24, 25, 54, 6, 54, 54, 54, 54,
- 54, 54, 54, 54, 54, 54, 54, 54,
- 54, 54, 54, 12, 13, 14, 54, 54,
- 54, 54, 54, 54, 54, 54, 54, 54,
- 54, 54, 25, 54, 6, 54, 54, 54,
- 54, 54, 54, 54, 54, 54, 54, 54,
- 54, 54, 54, 11, 12, 13, 14, 54,
- 54, 54, 54, 54, 54, 20, 21, 22,
- 54, 23, 24, 25, 54, 6, 54, 54,
- 54, 54, 54, 54, 54, 54, 54, 54,
- 54, 54, 54, 54, 11, 12, 13, 14,
- 54, 54, 54, 54, 54, 54, 54, 21,
- 22, 54, 23, 24, 25, 54, 6, 54,
- 54, 54, 54, 54, 54, 54, 54, 54,
- 54, 54, 54, 54, 54, 11, 12, 13,
- 14, 54, 54, 54, 54, 54, 54, 54,
- 54, 22, 54, 23, 24, 25, 54, 6,
- 54, 54, 54, 54, 54, 54, 54, 54,
- 54, 54, 54, 54, 54, 10, 11, 12,
- 13, 14, 54, 16, 10, 54, 54, 54,
- 20, 21, 22, 54, 23, 24, 25, 54,
- 6, 54, 54, 54, 54, 54, 54, 54,
- 54, 54, 54, 54, 54, 54, 10, 11,
- 12, 13, 14, 54, 54, 10, 54, 54,
- 54, 20, 21, 22, 54, 23, 24, 25,
- 54, 6, 54, 54, 54, 54, 54, 54,
- 54, 54, 54, 54, 54, 54, 54, 10,
- 11, 12, 13, 14, 15, 16, 10, 54,
- 54, 54, 20, 21, 22, 54, 23, 24,
- 25, 54, 6, 54, 54, 1, 55, 54,
- 54, 54, 54, 54, 54, 54, 54, 54,
+ 24, 25, 4, 4, 4, 26, 4, 28,
+ 27, 30, 29, 29, 31, 32, 29, 29,
+ 29, 29, 29, 29, 29, 29, 33, 34,
+ 35, 36, 37, 38, 39, 40, 34, 41,
+ 33, 42, 43, 44, 45, 29, 46, 47,
+ 48, 29, 30, 29, 29, 31, 32, 29,
+ 29, 29, 29, 29, 29, 29, 29, 49,
+ 34, 35, 36, 37, 38, 39, 40, 34,
+ 41, 42, 42, 43, 44, 45, 29, 46,
+ 47, 48, 29, 31, 50, 30, 29, 29,
+ 31, 32, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 34, 35, 36, 37, 38,
+ 39, 40, 34, 41, 42, 42, 43, 44,
+ 45, 29, 46, 47, 48, 29, 30, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 34, 35, 36, 37,
+ 38, 29, 29, 29, 29, 29, 29, 43,
+ 44, 45, 29, 46, 47, 48, 29, 30,
+ 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 35, 36,
+ 37, 38, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 46, 47, 48, 29,
+ 30, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29,
+ 36, 37, 38, 29, 30, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 37, 38, 29,
+ 30, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 38, 29, 30, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 36, 37, 38, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 46, 47, 48, 29, 30, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 36, 37, 38,
+ 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 47, 48, 29, 30, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 36, 37,
+ 38, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 48, 29, 30,
+ 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 35, 36,
+ 37, 38, 29, 29, 29, 29, 29, 29,
+ 43, 44, 45, 29, 46, 47, 48, 29,
+ 30, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 35,
+ 36, 37, 38, 29, 29, 29, 29, 29,
+ 29, 29, 44, 45, 29, 46, 47, 48,
+ 29, 30, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29,
+ 35, 36, 37, 38, 29, 29, 29, 29,
+ 29, 29, 29, 29, 45, 29, 46, 47,
+ 48, 29, 30, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29,
+ 34, 35, 36, 37, 38, 29, 40, 34,
+ 29, 29, 29, 43, 44, 45, 29, 46,
+ 47, 48, 29, 30, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 34, 35, 36, 37, 38, 29, 51,
+ 34, 29, 29, 29, 43, 44, 45, 29,
+ 46, 47, 48, 29, 30, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 34, 35, 36, 37, 38, 29,
+ 29, 34, 29, 29, 29, 43, 44, 45,
+ 29, 46, 47, 48, 29, 30, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 34, 35, 36, 37, 38,
+ 39, 40, 34, 29, 29, 29, 43, 44,
+ 45, 29, 46, 47, 48, 29, 30, 29,
+ 29, 31, 32, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 34, 35, 36, 37,
+ 38, 39, 40, 34, 41, 29, 42, 43,
+ 44, 45, 29, 46, 47, 48, 29, 30,
+ 29, 29, 31, 32, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 34, 35, 36,
+ 37, 38, 39, 40, 34, 41, 33, 42,
+ 43, 44, 45, 29, 46, 47, 48, 29,
+ 53, 52, 52, 52, 52, 52, 52, 52,
+ 54, 52, 5, 55, 53, 52, 6, 56,
+ 56, 1, 57, 56, 56, 56, 56, 56,
+ 56, 56, 56, 58, 10, 11, 12, 13,
+ 14, 15, 16, 10, 17, 19, 19, 20,
+ 21, 22, 56, 23, 24, 25, 56, 6,
+ 56, 56, 1, 57, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 10, 11, 12,
+ 13, 14, 15, 16, 10, 17, 19, 19,
+ 20, 21, 22, 56, 23, 24, 25, 56,
+ 6, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 10, 11,
+ 12, 13, 14, 56, 56, 56, 56, 56,
+ 56, 20, 21, 22, 56, 23, 24, 25,
+ 56, 6, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56,
+ 11, 12, 13, 14, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 23, 24,
+ 25, 56, 6, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 12, 13, 14, 56, 6, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 13,
+ 14, 56, 6, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 14, 56, 6, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 12, 13,
+ 14, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 23, 24, 25, 56, 6,
+ 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 12,
+ 13, 14, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 24, 25, 56,
+ 6, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56,
+ 12, 13, 14, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 25,
+ 56, 6, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56,
+ 11, 12, 13, 14, 56, 56, 56, 56,
+ 56, 56, 20, 21, 22, 56, 23, 24,
+ 25, 56, 6, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 11, 12, 13, 14, 56, 56, 56,
+ 56, 56, 56, 56, 21, 22, 56, 23,
+ 24, 25, 56, 6, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 11, 12, 13, 14, 56, 56,
+ 56, 56, 56, 56, 56, 56, 22, 56,
+ 23, 24, 25, 56, 6, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 10, 11, 12, 13, 14, 56,
+ 16, 10, 56, 56, 56, 20, 21, 22,
+ 56, 23, 24, 25, 56, 6, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 10, 11, 12, 13, 14,
+ 56, 59, 10, 56, 56, 56, 20, 21,
+ 22, 56, 23, 24, 25, 56, 6, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 10, 11, 12, 13,
+ 14, 56, 56, 10, 56, 56, 56, 20,
+ 21, 22, 56, 23, 24, 25, 56, 6,
+ 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 56, 56, 56, 56, 10, 11, 12,
+ 13, 14, 15, 16, 10, 56, 56, 56,
+ 20, 21, 22, 56, 23, 24, 25, 56,
+ 6, 56, 56, 1, 57, 56, 56, 56,
+ 56, 56, 56, 56, 56, 56, 10, 11,
+ 12, 13, 14, 15, 16, 10, 17, 56,
+ 19, 20, 21, 22, 56, 23, 24, 25,
+ 56, 1, 60, 3, 56, 56, 56, 3,
+ 56, 56, 6, 56, 56, 1, 57, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56,
10, 11, 12, 13, 14, 15, 16, 10,
- 17, 54, 19, 20, 21, 22, 54, 23,
- 24, 25, 54, 1, 57, 3, 54, 54,
- 54, 3, 54, 54, 6, 54, 54, 1,
- 55, 54, 54, 54, 54, 54, 54, 54,
- 54, 54, 10, 11, 12, 13, 14, 15,
- 16, 10, 17, 18, 19, 20, 21, 22,
- 54, 23, 24, 25, 54, 6, 54, 54,
- 1, 55, 54, 54, 54, 54, 54, 54,
- 54, 54, 54, 10, 11, 12, 13, 14,
- 15, 16, 10, 17, 18, 19, 20, 21,
- 22, 54, 23, 24, 25, 54, 59, 58,
- 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 58, 58, 58, 58, 58, 58,
- 58, 58, 59, 60, 58, 59, 60, 58,
- 60, 58, 0
+ 17, 18, 19, 20, 21, 22, 56, 23,
+ 24, 25, 56, 6, 56, 56, 1, 57,
+ 56, 56, 56, 56, 56, 56, 56, 56,
+ 56, 10, 11, 12, 13, 14, 15, 16,
+ 10, 17, 18, 19, 20, 21, 22, 56,
+ 23, 24, 25, 56, 62, 61, 61, 61,
+ 61, 61, 61, 61, 61, 61, 61, 61,
+ 61, 61, 61, 61, 61, 61, 61, 61,
+ 62, 63, 61, 62, 63, 61, 63, 61,
+ 3, 60, 60, 60, 3, 60, 0
};
static const char _use_syllable_machine_trans_targs[] = {
- 1, 26, 2, 3, 1, 23, 1, 43,
- 44, 46, 28, 29, 30, 31, 32, 39,
- 40, 41, 45, 42, 36, 37, 38, 33,
- 34, 35, 1, 1, 1, 1, 4, 5,
- 22, 7, 8, 9, 10, 11, 18, 19,
- 20, 21, 15, 16, 17, 12, 13, 14,
- 6, 1, 1, 24, 25, 1, 1, 0,
- 27, 1, 1, 47, 48
+ 1, 27, 2, 3, 1, 24, 1, 45,
+ 46, 48, 29, 30, 31, 32, 33, 40,
+ 41, 43, 47, 44, 37, 38, 39, 34,
+ 35, 36, 51, 1, 1, 1, 1, 4,
+ 5, 23, 7, 8, 9, 10, 11, 18,
+ 19, 21, 22, 15, 16, 17, 12, 13,
+ 14, 6, 1, 20, 1, 25, 26, 1,
+ 1, 0, 28, 42, 1, 1, 49, 50
};
static const char _use_syllable_machine_trans_actions[] = {
1, 2, 0, 0, 5, 0, 6, 0,
2, 0, 0, 0, 0, 0, 0, 0,
0, 0, 2, 2, 0, 0, 0, 0,
- 0, 0, 7, 8, 9, 10, 0, 0,
+ 0, 0, 0, 7, 8, 9, 10, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
- 0, 11, 12, 0, 0, 13, 14, 0,
- 2, 15, 16, 0, 0
+ 0, 0, 11, 0, 12, 0, 0, 13,
+ 14, 0, 2, 0, 15, 16, 0, 0
};
static const char _use_syllable_machine_to_state_actions[] = {
@@ -257,7 +266,7 @@ static const char _use_syllable_machine_to_state_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
- 0
+ 0, 0, 0, 0
};
static const char _use_syllable_machine_from_state_actions[] = {
@@ -267,17 +276,17 @@ static const char _use_syllable_machine_from_state_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
- 0
+ 0, 0, 0, 0
};
static const short _use_syllable_machine_eof_trans[] = {
- 1, 0, 27, 29, 29, 50, 29, 29,
- 29, 29, 29, 29, 29, 29, 29, 29,
- 29, 29, 29, 29, 29, 29, 29, 51,
- 54, 51, 55, 55, 55, 55, 55, 55,
- 55, 55, 55, 55, 55, 55, 55, 55,
- 55, 55, 55, 58, 55, 55, 59, 59,
- 59
+ 1, 0, 28, 30, 30, 51, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 53, 56, 53, 57, 57, 57, 57, 57,
+ 57, 57, 57, 57, 57, 57, 57, 57,
+ 57, 57, 57, 57, 57, 61, 57, 57,
+ 62, 62, 62, 61
};
static const int use_syllable_machine_start = 1;
@@ -291,7 +300,7 @@ static const int use_syllable_machine_en_main = 1;
-#line 138 "hb-ot-shape-complex-use-machine.rl"
+#line 140 "hb-ot-shape-complex-use-machine.rl"
#define found_syllable(syllable_type) \
@@ -311,7 +320,7 @@ find_syllables (hb_buffer_t *buffer)
int cs;
hb_glyph_info_t *info = buffer->info;
-#line 315 "hb-ot-shape-complex-use-machine.hh"
+#line 324 "hb-ot-shape-complex-use-machine.hh"
{
cs = use_syllable_machine_start;
ts = 0;
@@ -319,7 +328,7 @@ find_syllables (hb_buffer_t *buffer)
act = 0;
}
-#line 159 "hb-ot-shape-complex-use-machine.rl"
+#line 161 "hb-ot-shape-complex-use-machine.rl"
p = 0;
@@ -328,7 +337,7 @@ find_syllables (hb_buffer_t *buffer)
unsigned int last = 0;
unsigned int syllable_serial = 1;
-#line 332 "hb-ot-shape-complex-use-machine.hh"
+#line 341 "hb-ot-shape-complex-use-machine.hh"
{
int _slen;
int _trans;
@@ -342,7 +351,7 @@ _resume:
#line 1 "NONE"
{ts = p;}
break;
-#line 346 "hb-ot-shape-complex-use-machine.hh"
+#line 355 "hb-ot-shape-complex-use-machine.hh"
}
_keys = _use_syllable_machine_trans_keys + (cs<<1);
@@ -365,58 +374,58 @@ _eof_trans:
{te = p+1;}
break;
case 8:
-#line 127 "hb-ot-shape-complex-use-machine.rl"
+#line 129 "hb-ot-shape-complex-use-machine.rl"
{te = p+1;{ found_syllable (independent_cluster); }}
break;
case 10:
-#line 129 "hb-ot-shape-complex-use-machine.rl"
+#line 131 "hb-ot-shape-complex-use-machine.rl"
{te = p+1;{ found_syllable (standard_cluster); }}
break;
case 6:
-#line 133 "hb-ot-shape-complex-use-machine.rl"
+#line 135 "hb-ot-shape-complex-use-machine.rl"
{te = p+1;{ found_syllable (broken_cluster); }}
break;
case 5:
-#line 134 "hb-ot-shape-complex-use-machine.rl"
+#line 136 "hb-ot-shape-complex-use-machine.rl"
{te = p+1;{ found_syllable (non_cluster); }}
break;
case 7:
-#line 127 "hb-ot-shape-complex-use-machine.rl"
+#line 129 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (independent_cluster); }}
break;
case 11:
-#line 128 "hb-ot-shape-complex-use-machine.rl"
+#line 130 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (virama_terminated_cluster); }}
break;
case 9:
-#line 129 "hb-ot-shape-complex-use-machine.rl"
+#line 131 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (standard_cluster); }}
break;
case 13:
-#line 130 "hb-ot-shape-complex-use-machine.rl"
+#line 132 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (number_joiner_terminated_cluster); }}
break;
case 12:
-#line 131 "hb-ot-shape-complex-use-machine.rl"
+#line 133 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (numeral_cluster); }}
break;
case 16:
-#line 132 "hb-ot-shape-complex-use-machine.rl"
+#line 134 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (symbol_cluster); }}
break;
case 14:
-#line 133 "hb-ot-shape-complex-use-machine.rl"
+#line 135 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (broken_cluster); }}
break;
case 15:
-#line 134 "hb-ot-shape-complex-use-machine.rl"
+#line 136 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (non_cluster); }}
break;
case 1:
-#line 133 "hb-ot-shape-complex-use-machine.rl"
+#line 135 "hb-ot-shape-complex-use-machine.rl"
{{p = ((te))-1;}{ found_syllable (broken_cluster); }}
break;
-#line 420 "hb-ot-shape-complex-use-machine.hh"
+#line 429 "hb-ot-shape-complex-use-machine.hh"
}
_again:
@@ -425,7 +434,7 @@ _again:
#line 1 "NONE"
{ts = 0;}
break;
-#line 429 "hb-ot-shape-complex-use-machine.hh"
+#line 438 "hb-ot-shape-complex-use-machine.hh"
}
if ( ++p != pe )
@@ -441,7 +450,7 @@ _again:
}
-#line 168 "hb-ot-shape-complex-use-machine.rl"
+#line 170 "hb-ot-shape-complex-use-machine.rl"
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-private.hh
index ae428cb5eb..3e763ae393 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-private.hh
@@ -87,7 +87,8 @@ enum use_category_t {
USE_VMPst = 39, /* VOWEL_MOD_POST */
USE_VMPre = 23, /* VOWEL_MOD_PRE */
USE_SMAbv = 41, /* SYM_MOD_ABOVE */
- USE_SMBlw = 42 /* SYM_MOD_BELOW */
+ USE_SMBlw = 42, /* SYM_MOD_BELOW */
+ USE_CS = 43 /* CONS_WITH_STACKER */
};
HB_INTERNAL USE_TABLE_ELEMENT_TYPE
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-table.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-table.cc
index 38c46d002d..fd6978f281 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-table.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-table.cc
@@ -6,12 +6,12 @@
*
* on files with these headers:
*
- * # IndicSyllabicCategory-9.0.0.txt
- * # Date: 2016-05-21, 02:46:00 GMT [RP]
- * # IndicPositionalCategory-9.0.0.txt
- * # Date: 2016-02-25, 00:48:00 GMT [RP]
- * # Blocks-9.0.0.txt
- * # Date: 2016-02-05, 23:48:00 GMT [KW]
+ * # IndicSyllabicCategory-10.0.0.txt
+ * # Date: 2017-05-31, 01:07:00 GMT [KW, RP]
+ * # IndicPositionalCategory-10.0.0.txt
+ * # Date: 2017-05-31, 01:07:00 GMT [RP]
+ * # Blocks-10.0.0.txt
+ * # Date: 2017-04-12, 17:30:00 GMT [KW]
* UnicodeData.txt does not have a header.
*/
@@ -19,6 +19,7 @@
#define B USE_B /* BASE */
#define CGJ USE_CGJ /* CGJ */
+#define CS USE_CS /* CONS_WITH_STACKER */
#define FM USE_FM /* CONS_FINAL_MOD */
#define GB USE_GB /* BASE_OTHER */
#define H USE_H /* HALANT */
@@ -97,7 +98,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 09C0 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, O, O, VPre, VPre, H, IND, O,
/* 09D0 */ O, O, O, O, O, O, O, VPst, O, O, O, O, B, B, O, B,
/* 09E0 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B,
- /* 09F0 */ B, B, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+ /* 09F0 */ B, B, O, O, O, O, O, O, O, O, O, O, B, O, O, O,
/* Gurmukhi */
@@ -119,7 +120,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 0AC0 */ VPst, VBlw, VBlw, VBlw, VBlw, VAbv, O, VAbv, VAbv, VAbv, O, VPst, VPst, H, O, O,
/* 0AD0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* 0AE0 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B,
- /* 0AF0 */ O, O, O, O, O, O, O, O, O, B, O, O, O, O, O, O,
+ /* 0AF0 */ O, O, O, O, O, O, O, O, O, B, VMAbv, VMAbv, VMAbv, CMAbv, CMAbv, CMAbv,
/* Oriya */
@@ -163,14 +164,14 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 0CC0 */ VAbv, VPst, VPst, VPst, VPst, O, VAbv, VAbv, VAbv, O, VAbv, VAbv, VAbv, H, O, O,
/* 0CD0 */ O, O, O, O, O, VPst, VPst, O, O, O, O, O, O, O, B, O,
/* 0CE0 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B,
- /* 0CF0 */ O, R, R, O, O, O, O, O, O, O, O, O, O, O, O, O,
+ /* 0CF0 */ O, CS, CS, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* Malayalam */
- /* 0D00 */ O, VMAbv, VMPst, VMPst, O, B, B, B, B, B, B, B, B, O, B, B,
+ /* 0D00 */ VMAbv, VMAbv, VMPst, VMPst, O, B, B, B, B, B, B, B, B, O, B, B,
/* 0D10 */ B, O, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 0D20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
- /* 0D30 */ B, B, B, B, B, B, B, B, B, B, B, O, O, B, VPst, VPst,
+ /* 0D30 */ B, B, B, B, B, B, B, B, B, B, B, VAbv, VAbv, B, VPst, VPst,
/* 0D40 */ VPst, VPst, VPst, VBlw, VBlw, O, VPre, VPre, VPre, O, VPre, VPre, VPre, H, R, O,
/* 0D50 */ O, O, O, O, IND, IND, IND, VPst, O, O, O, O, O, O, O, B,
/* 0D60 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B,
@@ -274,9 +275,9 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 1A20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1A30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1A40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
- /* 1A50 */ B, B, B, B, B, MPre, MBlw, FPst, FAbv, FAbv, FAbv, FBlw, FBlw, FBlw, FBlw, O,
+ /* 1A50 */ B, B, B, B, B, MPre, MBlw, SUB, FAbv, FAbv, FAbv, SUB, SUB, SUB, SUB, O,
/* 1A60 */ H, VPst, VAbv, VPst, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VAbv, VBlw, VPst, VPre, VPre,
- /* 1A70 */ VPre, VPre, VPre, VAbv, VAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, FM, FM, FM, O, O, FM,
+ /* 1A70 */ VPre, VPre, VPre, VAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VAbv, FM, FM, O, O, FBlw,
/* 1A80 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
/* 1A90 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
@@ -323,7 +324,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 1CD0 */ VMAbv, VMAbv, VMAbv, O, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMAbv, VMAbv, VMBlw, VMBlw, VMBlw, VMBlw,
/* 1CE0 */ VMAbv, VMPst, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, O, O, O, O, VMBlw, O, O,
- /* 1CF0 */ O, O, VMPst, VMPst, VMAbv, O, O, O, VMAbv, VMAbv, O, O, O, O, O, O,
+ /* 1CF0 */ O, O, VMPst, VMPst, VMAbv, O, O, VMPst, VMAbv, VMAbv, O, O, O, O, O, O,
#define use_offset_0x1df8u 2552
@@ -347,7 +348,14 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 2070 */ O, O, O, O, FM, O, O, O, O, O, O, O, O, O, O, O,
/* 2080 */ O, O, FM, FM, FM, O, O, O,
-#define use_offset_0xa800u 2616
+#define use_offset_0x20f0u 2616
+
+
+ /* Combining Diacritical Marks for Symbols */
+
+ /* 20F0 */ VMAbv, O, O, O, O, O, O, O,
+
+#define use_offset_0xa800u 2624
/* Syloti Nagri */
@@ -369,14 +377,14 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* A880 */ VMPst, VMPst, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* A890 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* A8A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
- /* A8B0 */ B, B, B, B, FPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst,
+ /* A8B0 */ B, B, B, B, MPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst,
/* A8C0 */ VPst, VPst, VPst, VPst, H, VMAbv, O, O, O, O, O, O, O, O, O, O,
/* A8D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
/* Devanagari Extended */
/* A8E0 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,
- /* A8F0 */ VMAbv, VMAbv, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
+ /* A8F0 */ VMAbv, VMAbv, B, B, O, O, O, O, O, O, O, O, O, O, O, O,
/* Kayah Li */
@@ -397,7 +405,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* A980 */ VMAbv, VMAbv, FAbv, VMPst, B, B, B, B, B, B, B, B, B, B, B, B,
/* A990 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* A9A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
- /* A9B0 */ B, B, B, CMAbv, VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VPre, VAbv, SUB, MPst, MPst,
+ /* A9B0 */ B, B, B, CMAbv, VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VPre, VAbv, SUB, MPst, MBlw,
/* A9C0 */ H, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* A9D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
@@ -410,7 +418,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* AA00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* AA10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
- /* AA20 */ B, B, B, B, B, B, B, B, B, VAbv, VAbv, VAbv, VAbv, VBlw, VAbv, VPre,
+ /* AA20 */ B, B, B, B, B, B, B, B, B, VMAbv, VAbv, VAbv, VAbv, VBlw, VAbv, VPre,
/* AA30 */ VPre, VAbv, VBlw, MPst, MPre, MBlw, MBlw, O, O, O, O, O, O, O, O, O,
/* AA40 */ B, B, B, FAbv, B, B, B, B, B, B, B, B, FAbv, FPst, O, O,
/* AA50 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
@@ -434,7 +442,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* AAE0 */ B, B, B, B, B, B, B, B, B, B, B, VPre, VBlw, VAbv, VPre, VPst,
/* AAF0 */ O, O, O, O, O, VMPst, H, O,
-#define use_offset_0xabc0u 3376
+#define use_offset_0xabc0u 3384
/* Meetei Mayek */
@@ -444,14 +452,14 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* ABE0 */ B, B, B, VPst, VPst, VAbv, VPst, VPst, VBlw, VPst, VPst, O, VMPst, VBlw, O, O,
/* ABF0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
-#define use_offset_0xfe00u 3440
+#define use_offset_0xfe00u 3448
/* Variation Selectors */
/* FE00 */ VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS,
-#define use_offset_0x10a00u 3456
+#define use_offset_0x10a00u 3464
/* Kharoshthi */
@@ -462,12 +470,12 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 10A30 */ B, B, B, B, O, O, O, O, CMAbv, CMBlw, CMBlw, O, O, O, O, H,
/* 10A40 */ B, B, B, B, B, B, B, B,
-#define use_offset_0x11000u 3528
+#define use_offset_0x11000u 3536
/* Brahmi */
- /* 11000 */ VMPst, VMAbv, VMPst, R, R, B, B, B, B, B, B, B, B, B, B, B,
+ /* 11000 */ VMPst, VMAbv, VMPst, CS, CS, B, B, B, B, B, B, B, B, B, B, B,
/* 11010 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 11020 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 11030 */ B, B, B, B, B, B, B, B, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw,
@@ -483,7 +491,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 110A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 110B0 */ VPst, VPre, VPst, VBlw, VBlw, VAbv, VAbv, VPst, VPst, H, CMBlw, O, O, O, O, O,
-#define use_offset_0x11100u 3720
+#define use_offset_0x11100u 3728
/* Chakma */
@@ -521,7 +529,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11220 */ B, B, B, B, B, B, B, B, B, B, B, B, VPst, VPst, VPst, VBlw,
/* 11230 */ VAbv, VAbv, VAbv, VAbv, VMAbv, H, CMAbv, CMAbv, O, O, O, O, O, O, VMAbv, O,
-#define use_offset_0x11280u 4040
+#define use_offset_0x11280u 4048
/* Multani */
@@ -545,11 +553,11 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11320 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B,
/* 11330 */ B, O, B, B, O, B, B, B, B, B, O, O, CMBlw, B, VPst, VPst,
/* 11340 */ VAbv, VPst, VPst, VPst, VPst, O, O, VPre, VPre, O, O, VPre, VPre, H, O, O,
- /* 11350 */ O, O, O, O, O, O, O, VPst, O, O, O, O, O, O, O, O,
+ /* 11350 */ O, O, O, O, O, O, O, VPst, O, O, O, O, O, O, B, B,
/* 11360 */ B, B, VPst, VPst, O, O, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O,
/* 11370 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O,
-#define use_offset_0x11400u 4288
+#define use_offset_0x11400u 4296
/* Newa */
@@ -572,7 +580,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 114C0 */ VMAbv, VMPst, H, CMBlw, B, O, O, O, O, O, O, O, O, O, O, O,
/* 114D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
-#define use_offset_0x11580u 4512
+#define use_offset_0x11580u 4520
/* Siddham */
@@ -615,7 +623,26 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11720 */ VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VAbv, VBlw, VAbv, VAbv, VAbv, O, O, O, O,
/* 11730 */ B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, O,
-#define use_offset_0x11c00u 4960
+#define use_offset_0x11a00u 4968
+
+
+ /* Zanabazar Square */
+
+ /* 11A00 */ B, VAbv, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, VAbv, VAbv, VBlw, B, B, B, B, B,
+ /* 11A10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 11A20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 11A30 */ B, B, B, FM, VBlw, VMAbv, VMAbv, VMAbv, VMAbv, VMPst, R, MBlw, MBlw, MBlw, MBlw, GB,
+ /* 11A40 */ O, O, O, O, O, GB, O, H, O, O, O, O, O, O, O, O,
+
+ /* Soyombo */
+
+ /* 11A50 */ B, VAbv, VBlw, VBlw, VAbv, VAbv, VAbv, VPst, VPst, VBlw, VBlw, VBlw, B, B, B, B,
+ /* 11A60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 11A70 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 11A80 */ B, B, B, B, O, O, R, R, R, R, FBlw, FBlw, FBlw, FBlw, FBlw, FBlw,
+ /* 11A90 */ FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, VMAbv, VMPst, CMAbv, H, O, O, O, O, O, O,
+
+#define use_offset_0x11c00u 5128
/* Bhaiksuki */
@@ -636,7 +663,19 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11CA0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, SUB, SUB, SUB, SUB, SUB, SUB, SUB,
/* 11CB0 */ VBlw, VPre, VBlw, VAbv, VPst, VMAbv, VMAbv, O,
-}; /* Table items: 5144; occupancy: 72% */
+#define use_offset_0x11d00u 5312
+
+
+ /* Masaram Gondi */
+
+ /* 11D00 */ B, B, B, B, B, B, B, O, B, B, O, B, B, B, B, B,
+ /* 11D10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 11D20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
+ /* 11D30 */ B, VAbv, VAbv, VAbv, VAbv, VAbv, VBlw, O, O, O, VAbv, O, VAbv, VAbv, O, VAbv,
+ /* 11D40 */ VMAbv, VMAbv, CMBlw, VAbv, VBlw, H, R, MBlw, O, O, O, O, O, O, O, O,
+ /* 11D50 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
+
+}; /* Table items: 5408; occupancy: 73% */
USE_TABLE_ELEMENT_TYPE
hb_use_get_categories (hb_codepoint_t u)
@@ -644,47 +683,50 @@ hb_use_get_categories (hb_codepoint_t u)
switch (u >> 12)
{
case 0x0u:
- if (hb_in_range (u, 0x0028u, 0x003Fu)) return use_table[u - 0x0028u + use_offset_0x0028u];
- if (hb_in_range (u, 0x00A0u, 0x00D7u)) return use_table[u - 0x00A0u + use_offset_0x00a0u];
- if (hb_in_range (u, 0x0900u, 0x0DF7u)) return use_table[u - 0x0900u + use_offset_0x0900u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x0028u, 0x003Fu)) return use_table[u - 0x0028u + use_offset_0x0028u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x00A0u, 0x00D7u)) return use_table[u - 0x00A0u + use_offset_0x00a0u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x0900u, 0x0DF7u)) return use_table[u - 0x0900u + use_offset_0x0900u];
if (unlikely (u == 0x034Fu)) return CGJ;
break;
case 0x1u:
- if (hb_in_range (u, 0x1000u, 0x109Fu)) return use_table[u - 0x1000u + use_offset_0x1000u];
- if (hb_in_range (u, 0x1700u, 0x17EFu)) return use_table[u - 0x1700u + use_offset_0x1700u];
- if (hb_in_range (u, 0x1900u, 0x1A9Fu)) return use_table[u - 0x1900u + use_offset_0x1900u];
- if (hb_in_range (u, 0x1B00u, 0x1C4Fu)) return use_table[u - 0x1B00u + use_offset_0x1b00u];
- if (hb_in_range (u, 0x1CD0u, 0x1CFFu)) return use_table[u - 0x1CD0u + use_offset_0x1cd0u];
- if (hb_in_range (u, 0x1DF8u, 0x1DFFu)) return use_table[u - 0x1DF8u + use_offset_0x1df8u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x1000u, 0x109Fu)) return use_table[u - 0x1000u + use_offset_0x1000u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x1700u, 0x17EFu)) return use_table[u - 0x1700u + use_offset_0x1700u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x1900u, 0x1A9Fu)) return use_table[u - 0x1900u + use_offset_0x1900u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x1B00u, 0x1C4Fu)) return use_table[u - 0x1B00u + use_offset_0x1b00u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x1CD0u, 0x1CFFu)) return use_table[u - 0x1CD0u + use_offset_0x1cd0u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x1DF8u, 0x1DFFu)) return use_table[u - 0x1DF8u + use_offset_0x1df8u];
break;
case 0x2u:
- if (hb_in_range (u, 0x2008u, 0x2017u)) return use_table[u - 0x2008u + use_offset_0x2008u];
- if (hb_in_range (u, 0x2060u, 0x2087u)) return use_table[u - 0x2060u + use_offset_0x2060u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x2008u, 0x2017u)) return use_table[u - 0x2008u + use_offset_0x2008u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x2060u, 0x2087u)) return use_table[u - 0x2060u + use_offset_0x2060u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x20F0u, 0x20F7u)) return use_table[u - 0x20F0u + use_offset_0x20f0u];
if (unlikely (u == 0x25CCu)) return GB;
break;
case 0xAu:
- if (hb_in_range (u, 0xA800u, 0xAAF7u)) return use_table[u - 0xA800u + use_offset_0xa800u];
- if (hb_in_range (u, 0xABC0u, 0xABFFu)) return use_table[u - 0xABC0u + use_offset_0xabc0u];
+ if (hb_in_range<hb_codepoint_t> (u, 0xA800u, 0xAAF7u)) return use_table[u - 0xA800u + use_offset_0xa800u];
+ if (hb_in_range<hb_codepoint_t> (u, 0xABC0u, 0xABFFu)) return use_table[u - 0xABC0u + use_offset_0xabc0u];
break;
case 0xFu:
- if (hb_in_range (u, 0xFE00u, 0xFE0Fu)) return use_table[u - 0xFE00u + use_offset_0xfe00u];
+ if (hb_in_range<hb_codepoint_t> (u, 0xFE00u, 0xFE0Fu)) return use_table[u - 0xFE00u + use_offset_0xfe00u];
break;
case 0x10u:
- if (hb_in_range (u, 0x10A00u, 0x10A47u)) return use_table[u - 0x10A00u + use_offset_0x10a00u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x10A00u, 0x10A47u)) return use_table[u - 0x10A00u + use_offset_0x10a00u];
break;
case 0x11u:
- if (hb_in_range (u, 0x11000u, 0x110BFu)) return use_table[u - 0x11000u + use_offset_0x11000u];
- if (hb_in_range (u, 0x11100u, 0x1123Fu)) return use_table[u - 0x11100u + use_offset_0x11100u];
- if (hb_in_range (u, 0x11280u, 0x11377u)) return use_table[u - 0x11280u + use_offset_0x11280u];
- if (hb_in_range (u, 0x11400u, 0x114DFu)) return use_table[u - 0x11400u + use_offset_0x11400u];
- if (hb_in_range (u, 0x11580u, 0x1173Fu)) return use_table[u - 0x11580u + use_offset_0x11580u];
- if (hb_in_range (u, 0x11C00u, 0x11CB7u)) return use_table[u - 0x11C00u + use_offset_0x11c00u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x11000u, 0x110BFu)) return use_table[u - 0x11000u + use_offset_0x11000u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x11100u, 0x1123Fu)) return use_table[u - 0x11100u + use_offset_0x11100u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x11280u, 0x11377u)) return use_table[u - 0x11280u + use_offset_0x11280u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x11400u, 0x114DFu)) return use_table[u - 0x11400u + use_offset_0x11400u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x11580u, 0x1173Fu)) return use_table[u - 0x11580u + use_offset_0x11580u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x11A00u, 0x11A9Fu)) return use_table[u - 0x11A00u + use_offset_0x11a00u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x11C00u, 0x11CB7u)) return use_table[u - 0x11C00u + use_offset_0x11c00u];
+ if (hb_in_range<hb_codepoint_t> (u, 0x11D00u, 0x11D5Fu)) return use_table[u - 0x11D00u + use_offset_0x11d00u];
if (unlikely (u == 0x1107Fu)) return HN;
break;
@@ -696,6 +738,7 @@ hb_use_get_categories (hb_codepoint_t u)
#undef B
#undef CGJ
+#undef CS
#undef FM
#undef GB
#undef H
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use.cc
index 5b19d5d74a..62acd697bd 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use.cc
@@ -144,7 +144,7 @@ collect_features_use (hb_ot_shape_planner_t *plan)
/* "Topographical features" */
for (unsigned int i = 0; i < ARRAY_LENGTH (arabic_features); i++)
map->add_feature (arabic_features[i], 1, F_NONE);
- map->add_gsub_pause (NULL);
+ map->add_gsub_pause (nullptr);
/* "Standard typographic presentation" and "Positional feature application" */
for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++)
@@ -199,7 +199,7 @@ data_create_use (const hb_ot_shape_plan_t *plan)
{
use_shape_plan_t *use_plan = (use_shape_plan_t *) calloc (1, sizeof (use_shape_plan_t));
if (unlikely (!use_plan))
- return NULL;
+ return nullptr;
use_plan->rphf_mask = plan->map.get_1_mask (HB_TAG('r','p','h','f'));
@@ -209,7 +209,7 @@ data_create_use (const hb_ot_shape_plan_t *plan)
if (unlikely (!use_plan->arabic_plan))
{
free (use_plan);
- return NULL;
+ return nullptr;
}
}
@@ -292,7 +292,7 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan,
if (use_plan->arabic_plan)
return;
- ASSERT_STATIC (INIT < 4 && ISOL < 4 && MEDI < 4 && FINA < 4);
+ static_assert ((INIT < 4 && ISOL < 4 && MEDI < 4 && FINA < 4), "");
hb_mask_t masks[4], all_masks = 0;
for (unsigned int i = 0; i < 4; i++)
{
@@ -354,6 +354,8 @@ setup_syllables (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer)
{
find_syllables (buffer);
+ foreach_syllable (buffer, start, end)
+ buffer->unsafe_to_break (start, end);
setup_rphf_mask (plan, buffer);
setup_topographical_masks (plan, buffer);
}
@@ -422,7 +424,7 @@ reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end)
{
syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
/* Only a few syllable types need reordering. */
- if (unlikely (!(FLAG_SAFE (syllable_type) &
+ if (unlikely (!(FLAG_UNSAFE (syllable_type) &
(FLAG (virama_terminated_cluster) |
FLAG (standard_cluster) |
FLAG (broken_cluster) |
@@ -572,28 +574,6 @@ decompose_use (const hb_ot_shape_normalize_context_t *c,
*/
case 0x1112Eu : *a = 0x11127u; *b= 0x11131u; return true;
case 0x1112Fu : *a = 0x11127u; *b= 0x11132u; return true;
-
- /*
- * Decompose split matras that don't have Unicode decompositions.
- */
-
- /* Limbu */
- case 0x1925u : *a = 0x1920u; *b= 0x1923u; return true;
- case 0x1926u : *a = 0x1920u; *b= 0x1924u; return true;
-
- /* Balinese */
- case 0x1B3Cu : *a = 0x1B42u; *b= 0x1B3Cu; return true;
-
-#if 0
- /* Lepcha */
- case 0x1C29u : *a = no decomp, -> LEFT; return true;
-
- /* Javanese */
- case 0xA9C0u : *a = no decomp, -> RIGHT; return true;
-
- /* Sharada */
- case 0x111BFu : *a = no decomp, -> ABOVE; return true;
-#endif
}
return (bool) c->unicode->decompose (ab, a, b);
@@ -615,18 +595,18 @@ compose_use (const hb_ot_shape_normalize_context_t *c,
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_use =
{
- "use",
collect_features_use,
- NULL, /* override_features */
+ nullptr, /* override_features */
data_create_use,
data_destroy_use,
- NULL, /* preprocess_text */
- NULL, /* postprocess_glyphs */
+ nullptr, /* preprocess_text */
+ nullptr, /* postprocess_glyphs */
HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,
decompose_use,
compose_use,
setup_masks_use,
- NULL, /* disable_otl */
+ nullptr, /* disable_otl */
+ nullptr, /* reorder_marks */
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY,
false, /* fallback_position */
};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc
index ea8312b223..458c8eaa04 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc
@@ -210,7 +210,7 @@ position_mark (const hb_ot_shape_plan_t *plan,
pos.x_offset = pos.y_offset = 0;
- /* We dont position LEFT and RIGHT marks. */
+ /* We don't position LEFT and RIGHT marks. */
/* X positioning */
switch (combining_class)
@@ -218,10 +218,10 @@ position_mark (const hb_ot_shape_plan_t *plan,
case HB_UNICODE_COMBINING_CLASS_DOUBLE_BELOW:
case HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE:
if (buffer->props.direction == HB_DIRECTION_LTR) {
- pos.x_offset += base_extents.x_bearing - mark_extents.width / 2 - mark_extents.x_bearing;
+ pos.x_offset += base_extents.x_bearing + base_extents.width - mark_extents.width / 2 - mark_extents.x_bearing;
break;
} else if (buffer->props.direction == HB_DIRECTION_RTL) {
- pos.x_offset += base_extents.x_bearing + base_extents.width - mark_extents.width / 2 - mark_extents.x_bearing;
+ pos.x_offset += base_extents.x_bearing - mark_extents.width / 2 - mark_extents.x_bearing;
break;
}
HB_FALLTHROUGH;
@@ -307,6 +307,9 @@ position_around_base (const hb_ot_shape_plan_t *plan,
unsigned int end)
{
hb_direction_t horiz_dir = HB_DIRECTION_INVALID;
+
+ buffer->unsafe_to_break (base, end);
+
hb_glyph_extents_t base_extents;
if (!font->get_glyph_extents (buffer->info[base].codepoint,
&base_extents))
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc
index 107617e81c..fd9e7c2a8d 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc
@@ -91,7 +91,7 @@ compose_unicode (const hb_ot_shape_normalize_context_t *c,
static inline void
set_glyph (hb_glyph_info_t &info, hb_font_t *font)
{
- font->get_nominal_glyph (info.codepoint, &info.glyph_index());
+ (void) font->get_nominal_glyph (info.codepoint, &info.glyph_index());
}
static inline void
@@ -345,14 +345,18 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
if (_hb_glyph_info_get_modified_combining_class (&buffer->info[end]) == 0)
break;
- /* We are going to do a O(n^2). Only do this if the sequence is short. */
- if (end - i > 10) {
+ /* We are going to do a O(n^2). Only do this if the sequence is short,
+ * but not too short ;). */
+ if (end - i < 2 || end - i > HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS) {
i = end;
continue;
}
buffer->sort (i, end, compare_combining_class);
+ if (plan->shaper->reorder_marks)
+ plan->shaper->reorder_marks (plan, buffer, i, end);
+
i = end;
}
@@ -369,46 +373,58 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
buffer->clear_output ();
count = buffer->len;
unsigned int starter = 0;
+ bool combine = true;
buffer->next_glyph ();
while (buffer->idx < count && !buffer->in_error)
{
hb_codepoint_t composed, glyph;
- if (/* We don't try to compose a non-mark character with it's preceding starter.
+ if (combine &&
+ /* 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 ||
- _hb_glyph_info_get_modified_combining_class (&buffer->prev()) < _hb_glyph_info_get_modified_combining_class (&buffer->cur())) &&
- /* And compose. */
- c.compose (&c,
- buffer->out_info[starter].codepoint,
- buffer->cur().codepoint,
- &composed) &&
- /* And the font has glyph for the composite. */
- font->get_nominal_glyph (composed, &glyph))
+ HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->cur())))
{
- /* Composes. */
- buffer->next_glyph (); /* Copy to out-buffer. */
- if (unlikely (buffer->in_error))
- return;
- buffer->merge_out_clusters (starter, buffer->out_len);
- buffer->out_len--; /* Remove the second composable. */
- /* Modify starter and carry on. */
- buffer->out_info[starter].codepoint = composed;
- buffer->out_info[starter].glyph_index() = glyph;
- _hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer);
-
- continue;
+ if (/* If there's anything between the starter and this char, they should have CCC
+ * smaller than this character's. */
+ (starter == buffer->out_len - 1 ||
+ info_cc (buffer->prev()) < info_cc (buffer->cur())) &&
+ /* And compose. */
+ c.compose (&c,
+ buffer->out_info[starter].codepoint,
+ buffer->cur().codepoint,
+ &composed) &&
+ /* And the font has glyph for the composite. */
+ font->get_nominal_glyph (composed, &glyph))
+ {
+ /* Composes. */
+ buffer->next_glyph (); /* Copy to out-buffer. */
+ if (unlikely (buffer->in_error))
+ return;
+ buffer->merge_out_clusters (starter, buffer->out_len);
+ buffer->out_len--; /* Remove the second composable. */
+ /* Modify starter and carry on. */
+ buffer->out_info[starter].codepoint = composed;
+ buffer->out_info[starter].glyph_index() = glyph;
+ _hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer);
+
+ continue;
+ }
+ else if (/* We sometimes custom-tailor the sorted order of marks. In that case, stop
+ * trying to combine as soon as combining-class drops. */
+ starter < buffer->out_len - 1 &&
+ info_cc (buffer->prev()) > info_cc (buffer->cur()))
+ combine = false;
}
/* Blocked, or doesn't compose. */
buffer->next_glyph ();
- if (_hb_glyph_info_get_modified_combining_class (&buffer->prev()) == 0)
+ if (info_cc (buffer->prev()) == 0)
+ {
starter = buffer->out_len - 1;
+ combine = true;
+ }
}
buffer->swap_buffers ();
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh
index 594e54c026..fe5d2b7f33 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh
@@ -73,7 +73,7 @@ struct hb_ot_shape_planner_t
hb_ot_shape_planner_t (const hb_shape_plan_t *master_plan) :
face (master_plan->face_unsafe),
props (master_plan->props),
- shaper (NULL),
+ shaper (nullptr),
map (face, &props) {}
~hb_ot_shape_planner_t (void) { map.finish (); }
@@ -99,7 +99,9 @@ struct hb_ot_shape_planner_t
}
private:
- NO_COPY (hb_ot_shape_planner_t);
+ /* No copy. */
+ hb_ot_shape_planner_t (const hb_ot_shape_planner_t &);
+ hb_ot_shape_planner_t &operator = (const hb_ot_shape_planner_t &);
};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc
index ddd6662e84..2f28b5620d 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc
@@ -70,7 +70,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
hb_ot_map_builder_t *map = &planner->map;
map->add_global_bool_feature (HB_TAG('r','v','r','n'));
- map->add_gsub_pause (NULL);
+ map->add_gsub_pause (nullptr);
switch (props->direction) {
case HB_DIRECTION_LTR:
@@ -108,7 +108,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
/* We really want to find a 'vert' feature if there's any in the font, no
* matter which script/langsys it is listed (or not) under.
* See various bugs referenced from:
- * https://github.com/behdad/harfbuzz/issues/63 */
+ * https://github.com/harfbuzz/harfbuzz/issues/63 */
map->add_feature (HB_TAG ('v','e','r','t'), 1, F_GLOBAL | F_GLOBAL_SEARCH);
}
@@ -128,6 +128,8 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
* shaper face data
*/
+HB_SHAPER_DATA_ENSURE_DEFINE(ot, face)
+
hb_ot_shaper_face_data_t *
_hb_ot_shaper_face_data_create (hb_face_t *face)
{
@@ -145,6 +147,8 @@ _hb_ot_shaper_face_data_destroy (hb_ot_shaper_face_data_t *data)
* shaper font data
*/
+HB_SHAPER_DATA_ENSURE_DEFINE(ot, font)
+
struct hb_ot_shaper_font_data_t {};
hb_ot_shaper_font_data_t *
@@ -172,7 +176,7 @@ _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan,
{
hb_ot_shape_plan_t *plan = (hb_ot_shape_plan_t *) calloc (1, sizeof (hb_ot_shape_plan_t));
if (unlikely (!plan))
- return NULL;
+ return nullptr;
hb_ot_shape_planner_t planner (shape_plan);
@@ -186,7 +190,7 @@ _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan,
if (plan->shaper->data_create) {
plan->data = plan->shaper->data_create (plan);
if (unlikely (!plan->data))
- return NULL;
+ return nullptr;
}
return plan;
@@ -271,8 +275,7 @@ hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font)
static void
hb_form_clusters (hb_buffer_t *buffer)
{
- if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII) ||
- buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES)
+ if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII))
return;
/* Loop duplicated in hb_ensure_native_direction(), and in _hb-coretext.cc */
@@ -284,11 +287,17 @@ hb_form_clusters (hb_buffer_t *buffer)
if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])) &&
!_hb_glyph_info_is_joiner (&info[i])))
{
- buffer->merge_clusters (base, i);
+ if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES)
+ buffer->merge_clusters (base, i);
+ else
+ buffer->unsafe_to_break (base, i);
base = i;
}
}
- buffer->merge_clusters (base, count);
+ if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES)
+ buffer->merge_clusters (base, count);
+ else
+ buffer->unsafe_to_break (base, count);
}
static void
@@ -362,7 +371,18 @@ hb_ot_shape_setup_masks_fraction (hb_ot_shape_context_t *c)
hb_buffer_t *buffer = c->buffer;
- /* TODO look in pre/post context text also. */
+ hb_mask_t pre_mask, post_mask;
+ if (HB_DIRECTION_IS_FORWARD (buffer->props.direction))
+ {
+ pre_mask = c->plan->numr_mask | c->plan->frac_mask;
+ post_mask = c->plan->frac_mask | c->plan->dnom_mask;
+ }
+ else
+ {
+ pre_mask = c->plan->frac_mask | c->plan->dnom_mask;
+ post_mask = c->plan->numr_mask | c->plan->frac_mask;
+ }
+
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
@@ -379,11 +399,13 @@ hb_ot_shape_setup_masks_fraction (hb_ot_shape_context_t *c)
HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER)
end++;
+ buffer->unsafe_to_break (start, end);
+
for (unsigned int j = start; j < i; j++)
- info[j].mask |= c->plan->numr_mask | c->plan->frac_mask;
+ info[j].mask |= pre_mask;
info[i].mask |= c->plan->frac_mask;
for (unsigned int j = i + 1; j < end; j++)
- info[j].mask |= c->plan->frac_mask | c->plan->dnom_mask;
+ info[j].mask |= post_mask;
i = end - 1;
}
@@ -494,9 +516,10 @@ hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c)
/* Merge cluster backward. */
if (cluster < info[j - 1].cluster)
{
+ unsigned int mask = info[i].mask;
unsigned int old_cluster = info[j - 1].cluster;
for (unsigned k = j; k && info[k - 1].cluster == old_cluster; k--)
- info[k - 1].cluster = cluster;
+ buffer->set_cluster (info[k - 1], cluster, mask);
}
continue;
}
@@ -562,8 +585,6 @@ hb_ot_substitute_default (hb_ot_shape_context_t *c)
{
hb_buffer_t *buffer = c->buffer;
- hb_ot_shape_initialize_masks (c);
-
hb_ot_mirror_chars (c);
HB_BUFFER_ALLOCATE_VAR (buffer, glyph_index);
@@ -672,9 +693,9 @@ hb_ot_position_default (hb_ot_shape_context_t *c)
static inline void
hb_ot_position_complex (hb_ot_shape_context_t *c)
{
- hb_ot_layout_position_start (c->font, c->buffer);
-
unsigned int count = c->buffer->len;
+ hb_glyph_info_t *info = c->buffer->info;
+ hb_glyph_position_t *pos = c->buffer->pos;
/* If the font has no GPOS, AND, no fallback positioning will
* happen, AND, direction is forward, then when zeroing mark
@@ -689,6 +710,17 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
!c->plan->shaper->fallback_position &&
HB_DIRECTION_IS_FORWARD (c->buffer->props.direction);
+ /* We change glyph origin to what GPOS expects (horizontal), apply GPOS, change it back. */
+
+ /* The nil glyph_h_origin() func returns 0, so no need to apply it. */
+ if (c->font->has_glyph_h_origin_func ())
+ for (unsigned int i = 0; i < count; i++)
+ c->font->add_glyph_h_origin (info[i].codepoint,
+ &pos[i].x_offset,
+ &pos[i].y_offset);
+
+ hb_ot_layout_position_start (c->font, c->buffer);
+
switch (c->plan->shaper->zero_width_marks)
{
case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
@@ -702,30 +734,8 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
}
if (likely (!c->fallback_positioning))
- {
- hb_glyph_info_t *info = c->buffer->info;
- hb_glyph_position_t *pos = c->buffer->pos;
-
- /* Change glyph origin to what GPOS expects (horizontal), apply GPOS, change it back. */
-
- /* The nil glyph_h_origin() func returns 0, so no need to apply it. */
- if (c->font->has_glyph_h_origin_func ())
- for (unsigned int i = 0; i < count; i++)
- c->font->add_glyph_h_origin (info[i].codepoint,
- &pos[i].x_offset,
- &pos[i].y_offset);
-
c->plan->position (c->font, c->buffer);
- /* The nil glyph_h_origin() func returns 0, so no need to apply it. */
- if (c->font->has_glyph_h_origin_func ())
- for (unsigned int i = 0; i < count; i++)
- c->font->subtract_glyph_h_origin (info[i].codepoint,
- &pos[i].x_offset,
- &pos[i].y_offset);
-
- }
-
switch (c->plan->shaper->zero_width_marks)
{
case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
@@ -742,6 +752,13 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
hb_ot_layout_position_finish_advances (c->font, c->buffer);
hb_ot_zero_width_default_ignorables (c);
hb_ot_layout_position_finish_offsets (c->font, c->buffer);
+
+ /* The nil glyph_h_origin() func returns 0, so no need to apply it. */
+ if (c->font->has_glyph_h_origin_func ())
+ for (unsigned int i = 0; i < count; i++)
+ c->font->subtract_glyph_h_origin (info[i].codepoint,
+ &pos[i].x_offset,
+ &pos[i].y_offset);
}
static inline void
@@ -767,6 +784,31 @@ hb_ot_position (hb_ot_shape_context_t *c)
_hb_buffer_deallocate_gsubgpos_vars (c->buffer);
}
+static inline void
+hb_propagate_flags (hb_buffer_t *buffer)
+{
+ /* Propagate cluster-level glyph flags to be the same on all cluster glyphs.
+ * Simplifies using them. */
+
+ if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK))
+ return;
+
+ hb_glyph_info_t *info = buffer->info;
+
+ foreach_cluster (buffer, start, end)
+ {
+ unsigned int mask = 0;
+ for (unsigned int i = start; i < end; i++)
+ if (info[i].mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK)
+ {
+ mask = HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
+ break;
+ }
+ if (mask)
+ for (unsigned int i = start; i < end; i++)
+ info[i].mask |= mask;
+ }
+}
/* Pull it all together! */
@@ -775,11 +817,16 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c)
{
c->buffer->deallocate_var_all ();
c->buffer->scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
- if (likely (!_hb_unsigned_int_mul_overflows (c->buffer->len, HB_BUFFER_MAX_EXPANSION_FACTOR)))
+ if (likely (!_hb_unsigned_int_mul_overflows (c->buffer->len, HB_BUFFER_MAX_LEN_FACTOR)))
{
- c->buffer->max_len = MAX (c->buffer->len * HB_BUFFER_MAX_EXPANSION_FACTOR,
+ c->buffer->max_len = MAX (c->buffer->len * HB_BUFFER_MAX_LEN_FACTOR,
(unsigned) HB_BUFFER_MAX_LEN_MIN);
}
+ if (likely (!_hb_unsigned_int_mul_overflows (c->buffer->len, HB_BUFFER_MAX_OPS_FACTOR)))
+ {
+ c->buffer->max_ops = MAX (c->buffer->len * HB_BUFFER_MAX_OPS_FACTOR,
+ (unsigned) HB_BUFFER_MAX_OPS_MIN);
+ }
bool disable_otl = c->plan->shaper->disable_otl && c->plan->shaper->disable_otl (c->plan);
//c->fallback_substitute = disable_otl || !hb_ot_layout_has_substitution (c->face);
@@ -793,8 +840,10 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c)
c->buffer->clear_output ();
+ hb_ot_shape_initialize_masks (c);
hb_set_unicode_props (c->buffer);
hb_insert_dotted_circle (c->buffer, c->font);
+
hb_form_clusters (c->buffer);
hb_ensure_native_direction (c->buffer);
@@ -810,11 +859,14 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c)
if (c->plan->shaper->postprocess_glyphs)
c->plan->shaper->postprocess_glyphs (c->plan, c->buffer, c->font);
+ hb_propagate_flags (c->buffer);
+
_hb_buffer_deallocate_unicode_vars (c->buffer);
c->buffer->props.direction = c->target_direction;
c->buffer->max_len = HB_BUFFER_MAX_LEN_DEFAULT;
+ c->buffer->max_ops = HB_BUFFER_MAX_OPS_DEFAULT;
c->buffer->deallocate_var_all ();
}
@@ -882,7 +934,7 @@ hb_ot_shape_glyphs_closure (hb_font_t *font,
{
hb_ot_shape_plan_t plan;
- const char *shapers[] = {"ot", NULL};
+ const char *shapers[] = {"ot", nullptr};
hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props,
features, num_features, shapers);
@@ -893,18 +945,19 @@ hb_ot_shape_glyphs_closure (hb_font_t *font,
for (unsigned int i = 0; i < count; i++)
add_char (font, buffer->unicode, mirror, info[i].codepoint, glyphs);
- hb_set_t lookups;
- lookups.init ();
- hb_ot_shape_plan_collect_lookups (shape_plan, HB_OT_TAG_GSUB, &lookups);
+ hb_set_t *lookups = hb_set_create ();
+ hb_ot_shape_plan_collect_lookups (shape_plan, HB_OT_TAG_GSUB, lookups);
/* And find transitive closure. */
- hb_set_t copy;
- copy.init ();
+ hb_set_t *copy = hb_set_create ();
do {
- copy.set (glyphs);
- for (hb_codepoint_t lookup_index = -1; hb_set_next (&lookups, &lookup_index);)
+ copy->set (glyphs);
+ for (hb_codepoint_t lookup_index = -1; hb_set_next (lookups, &lookup_index);)
hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs);
- } while (!copy.is_equal (glyphs));
+ } while (!copy->is_equal (glyphs));
+ hb_set_destroy (copy);
+
+ hb_set_destroy (lookups);
hb_shape_plan_destroy (shape_plan);
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc
index 5f21ac0967..1338c31732 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc
@@ -28,9 +28,6 @@
#include "hb-private.hh"
-#include <string.h>
-
-
/* hb_script_t */
@@ -201,6 +198,7 @@ static const LangTag ot_languages[] = {
{"alt", HB_TAG('A','L','T',' ')}, /* [Southern] Altai */
{"am", HB_TAG('A','M','H',' ')}, /* Amharic */
{"amf", HB_TAG('H','B','N',' ')}, /* Hammer-Banna */
+ {"amw", HB_TAG('S','Y','R',' ')}, /* Western Neo-Aramaic */
{"an", HB_TAG('A','R','G',' ')}, /* Aragonese */
{"ang", HB_TAG('A','N','G',' ')}, /* Old English (ca. 450-1100) */
{"ar", HB_TAG('A','R','A',' ')}, /* Arabic [macrolanguage] */
@@ -239,6 +237,7 @@ static const LangTag ot_languages[] = {
{"bg", HB_TAG('B','G','R',' ')}, /* Bulgarian */
{"bgc", HB_TAG('B','G','C',' ')}, /* Haryanvi */
{"bgq", HB_TAG('B','G','Q',' ')}, /* Bagri */
+ {"bgr", HB_TAG('Q','I','N',' ')}, /* Bawm Chin */
{"bhb", HB_TAG('B','H','I',' ')}, /* Bhili */
{"bhk", HB_TAG('B','I','K',' ')}, /* Albay Bicolano (retired code) */
{"bho", HB_TAG('B','H','O',' ')}, /* Bhojpuri */
@@ -270,18 +269,37 @@ static const LangTag ot_languages[] = {
{"ca", HB_TAG('C','A','T',' ')}, /* Catalan */
{"cak", HB_TAG('C','A','K',' ')}, /* Kaqchikel */
{"cbk", HB_TAG('C','B','K',' ')}, /* Chavacano */
+ {"cbl", HB_TAG('Q','I','N',' ')}, /* Bualkhaw Chin */
+ {"cco", HB_TAG('C','C','H','N')}, /* Chinantec */
{"ce", HB_TAG('C','H','E',' ')}, /* Chechen */
{"ceb", HB_TAG('C','E','B',' ')}, /* Cebuano */
+ {"cfm", HB_TAG('H','A','L',' ')}, /* Halam/Falam Chin */
{"cgg", HB_TAG('C','G','G',' ')}, /* Chiga */
{"ch", HB_TAG('C','H','A',' ')}, /* Chamorro */
+ {"chj", HB_TAG('C','C','H','N')}, /* Chinantec */
{"chk", HB_TAG('C','H','K','0')}, /* Chuukese */
{"cho", HB_TAG('C','H','O',' ')}, /* Choctaw */
{"chp", HB_TAG('C','H','P',' ')}, /* Chipewyan */
+ {"chq", HB_TAG('C','C','H','N')}, /* Chinantec */
{"chr", HB_TAG('C','H','R',' ')}, /* Cherokee */
{"chy", HB_TAG('C','H','Y',' ')}, /* Cheyenne */
+ {"chz", HB_TAG('C','C','H','N')}, /* Chinantec */
+ {"cja", HB_TAG('C','J','A',' ')}, /* Western Cham */
+ {"cjm", HB_TAG('C','J','M',' ')}, /* Eastern Cham */
+ {"cka", HB_TAG('Q','I','N',' ')}, /* Khumi Awa Chin */
{"ckb", HB_TAG('K','U','R',' ')}, /* Central Kurdish (Sorani) */
{"ckt", HB_TAG('C','H','K',' ')}, /* Chukchi */
+ {"cld", HB_TAG('S','Y','R',' ')}, /* Chaldean Neo-Aramaic */
+ {"cle", HB_TAG('C','C','H','N')}, /* Chinantec */
+ {"cmr", HB_TAG('Q','I','N',' ')}, /* Mro-Khimi Chin */
+ {"cnb", HB_TAG('Q','I','N',' ')}, /* Chinbon Chin */
+ {"cnh", HB_TAG('Q','I','N',' ')}, /* Hakha Chin */
+ {"cnk", HB_TAG('Q','I','N',' ')}, /* Khumi Chin */
+ {"cnl", HB_TAG('C','C','H','N')}, /* Chinantec */
+ {"cnt", HB_TAG('C','C','H','N')}, /* Chinantec */
+ {"cnw", HB_TAG('Q','I','N',' ')}, /* Ngawn Chin */
{"cop", HB_TAG('C','O','P',' ')}, /* Coptic */
+ {"cpa", HB_TAG('C','C','H','N')}, /* Chinantec */
{"cpp", HB_TAG('C','P','P',' ')}, /* Creoles */
{"cr", HB_TAG('C','R','E',' ')}, /* Cree */
{"cre", HB_TAG('Y','C','R',' ')}, /* Y-Cree */
@@ -292,15 +310,26 @@ static const LangTag ot_languages[] = {
{"crm", HB_TAG('M','C','R',' ')}, /* Moose Cree */
{"crx", HB_TAG('C','R','R',' ')}, /* Carrier */
{"cs", HB_TAG('C','S','Y',' ')}, /* Czech */
+ {"csa", HB_TAG('C','C','H','N')}, /* Chinantec */
{"csb", HB_TAG('C','S','B',' ')}, /* Kashubian */
+ {"csh", HB_TAG('Q','I','N',' ')}, /* Asho Chin */
+ {"cso", HB_TAG('C','C','H','N')}, /* Chinantec */
+ {"csy", HB_TAG('Q','I','N',' ')}, /* Siyin Chin */
+ {"ctd", HB_TAG('Q','I','N',' ')}, /* Tedim Chin */
+ {"cte", HB_TAG('C','C','H','N')}, /* Chinantec */
{"ctg", HB_TAG('C','T','G',' ')}, /* Chittagonian */
+ {"ctl", HB_TAG('C','C','H','N')}, /* Chinantec */
{"cts", HB_TAG('B','I','K',' ')}, /* Northern Catanduanes Bikol */
{"cu", HB_TAG('C','S','L',' ')}, /* Church Slavic */
+ {"cuc", HB_TAG('C','C','H','N')}, /* Chinantec */
{"cuk", HB_TAG('C','U','K',' ')}, /* San Blas Kuna */
{"cv", HB_TAG('C','H','U',' ')}, /* Chuvash */
+ {"cvn", HB_TAG('C','C','H','N')}, /* Chinantec */
{"cwd", HB_TAG('D','C','R',' ')}, /* Woods Cree */
{"cy", HB_TAG('W','E','L',' ')}, /* Welsh */
+ {"czt", HB_TAG('Q','I','N',' ')}, /* Zotung Chin */
{"da", HB_TAG('D','A','N',' ')}, /* Danish */
+ {"dao", HB_TAG('Q','I','N',' ')}, /* Daai Chin */
{"dap", HB_TAG('N','I','S',' ')}, /* Nisi (India) */
{"dar", HB_TAG('D','A','R',' ')}, /* Dargwa */
{"dax", HB_TAG('D','A','X',' ')}, /* Dayi */
@@ -343,7 +372,7 @@ static const LangTag ot_languages[] = {
{"fi", HB_TAG('F','I','N',' ')}, /* Finnish */
{"fil", HB_TAG('P','I','L',' ')}, /* Filipino */
{"fj", HB_TAG('F','J','I',' ')}, /* Fijian */
- {"flm", HB_TAG('H','A','L',' ')}, /* Halam */
+ {"flm", HB_TAG('H','A','L',' ')}, /* Halam/Falam Chin [retired ISO639 code] */
{"fo", HB_TAG('F','O','S',' ')}, /* Faroese */
{"fon", HB_TAG('F','O','N',' ')}, /* Fon */
{"fr", HB_TAG('F','R','A',' ')}, /* French */
@@ -365,7 +394,6 @@ static const LangTag ot_languages[] = {
{"gkp", HB_TAG('G','K','P',' ')}, /* Kpelle (Guinea) */
{"gl", HB_TAG('G','A','L',' ')}, /* Galician */
{"gld", HB_TAG('N','A','N',' ')}, /* Nanai */
- {"gle", HB_TAG('I','R','T',' ')}, /* Irish Traditional */
{"glk", HB_TAG('G','L','K',' ')}, /* Gilaki */
{"gn", HB_TAG('G','U','A',' ')}, /* Guarani [macrolanguage] */
{"gnn", HB_TAG('G','N','N',' ')}, /* Gumatj */
@@ -390,6 +418,7 @@ static const LangTag ot_languages[] = {
{"he", HB_TAG('I','W','R',' ')}, /* Hebrew */
{"hi", HB_TAG('H','I','N',' ')}, /* Hindi */
{"hil", HB_TAG('H','I','L',' ')}, /* Hiligaynon */
+ {"hlt", HB_TAG('Q','I','N',' ')}, /* Matu Chin */
{"hmn", HB_TAG('H','M','N',' ')}, /* Hmong */
{"hnd", HB_TAG('H','N','D',' ')}, /* [Southern] Hindko */
{"hne", HB_TAG('C','H','H',' ')}, /* Chattisgarhi */
@@ -522,7 +551,6 @@ static const LangTag ot_languages[] = {
{"mag", HB_TAG('M','A','G',' ')}, /* Magahi */
{"mai", HB_TAG('M','T','H',' ')}, /* Maithili */
{"mak", HB_TAG('M','K','R',' ')}, /* Makasar */
- {"mal", HB_TAG('M','A','L',' ')}, /* Malayalam */
{"mam", HB_TAG('M','A','M',' ')}, /* Mam */
{"man", HB_TAG('M','N','K',' ')}, /* Manding/Mandingo [macrolanguage] */
{"mdc", HB_TAG('M','L','E',' ')}, /* Male (Papua New Guinea) */
@@ -553,6 +581,7 @@ static const LangTag ot_languages[] = {
{"mos", HB_TAG('M','O','S',' ')}, /* Mossi */
{"mpe", HB_TAG('M','A','J',' ')}, /* Majang */
{"mr", HB_TAG('M','A','R',' ')}, /* Marathi */
+ {"mrh", HB_TAG('Q','I','N',' ')}, /* Mara Chin */
{"mrj", HB_TAG('H','M','A',' ')}, /* High Mari */
{"ms", HB_TAG('M','L','Y',' ')}, /* Malay [macrolanguage] */
{"msc", HB_TAG('M','N','K',' ')}, /* Sankaran Maninka */
@@ -617,6 +646,7 @@ static const LangTag ot_languages[] = {
{"pcc", HB_TAG('P','C','C',' ')}, /* Bouyei */
{"pcd", HB_TAG('P','C','D',' ')}, /* Picard */
{"pce", HB_TAG('P','L','G',' ')}, /* [Ruching] Palaung */
+ {"pck", HB_TAG('Q','I','N',' ')}, /* Paite Chin */
{"pdc", HB_TAG('P','D','C',' ')}, /* Pennsylvania German */
{"pes", HB_TAG('F','A','R',' ')}, /* Iranian Persian */
{"phk", HB_TAG('P','H','K',' ')}, /* Phake */
@@ -674,6 +704,7 @@ static const LangTag ot_languages[] = {
{"se", HB_TAG('N','S','M',' ')}, /* Northern Sami */
{"seh", HB_TAG('S','N','A',' ')}, /* Sena */
{"sel", HB_TAG('S','E','L',' ')}, /* Selkup */
+ {"sez", HB_TAG('Q','I','N',' ')}, /* Senthang Chin */
{"sg", HB_TAG('S','G','O',' ')}, /* Sango */
{"sga", HB_TAG('S','G','A',' ')}, /* Old Irish (to 900) */
{"sgs", HB_TAG('S','G','S',' ')}, /* Samogitian */
@@ -713,12 +744,15 @@ static const LangTag ot_languages[] = {
{"swh", HB_TAG('S','W','K',' ')}, /* Kiswahili/Swahili */
{"swv", HB_TAG('M','A','W',' ')}, /* Shekhawati */
{"sxu", HB_TAG('S','X','U',' ')}, /* Upper Saxon */
+ {"syc", HB_TAG('S','Y','R',' ')}, /* Classical Syriac */
{"syl", HB_TAG('S','Y','L',' ')}, /* Sylheti */
{"syr", HB_TAG('S','Y','R',' ')}, /* Syriac [macrolanguage] */
{"szl", HB_TAG('S','Z','L',' ')}, /* Silesian */
{"ta", HB_TAG('T','A','M',' ')}, /* Tamil */
{"tab", HB_TAG('T','A','B',' ')}, /* Tabasaran */
+ {"tcp", HB_TAG('Q','I','N',' ')}, /* Tawr Chin */
{"tcy", HB_TAG('T','U','L',' ')}, /* Tulu */
+ {"tcz", HB_TAG('Q','I','N',' ')}, /* Thado Chin */
{"tdd", HB_TAG('T','D','D',' ')}, /* Tai Nüa */
{"te", HB_TAG('T','E','L',' ')}, /* Telugu */
{"tem", HB_TAG('T','M','N',' ')}, /* Temne */
@@ -786,11 +820,13 @@ static const LangTag ot_languages[] = {
{"yap", HB_TAG('Y','A','P',' ')}, /* Yapese */
{"yi", HB_TAG('J','I','I',' ')}, /* Yiddish [macrolanguage] */
{"yo", HB_TAG('Y','B','A',' ')}, /* Yoruba */
+ {"yos", HB_TAG('Q','I','N',' ')}, /* Yos, deprecated by IANA in favor of Zou [zom] */
{"yso", HB_TAG('N','I','S',' ')}, /* Nisi (China) */
{"za", HB_TAG('Z','H','A',' ')}, /* Chuang/Zhuang [macrolanguage] */
{"zea", HB_TAG('Z','E','A',' ')}, /* Zeeuws */
{"zgh", HB_TAG('Z','G','H',' ')}, /* Standard Morrocan Tamazigh */
{"zne", HB_TAG('Z','N','D',' ')}, /* Zande */
+ {"zom", HB_TAG('Q','I','N',' ')}, /* Zou */
{"zu", HB_TAG('Z','U','L',' ')}, /* Zulu */
{"zum", HB_TAG('L','R','C',' ')}, /* Kumzari */
{"zza", HB_TAG('Z','Z','A',' ')}, /* Zazaki */
@@ -843,9 +879,11 @@ static const LangTagLong ot_languages_zh[] = {
};
static int
-lang_compare_first_component (const char *a,
- const char *b)
+lang_compare_first_component (const void *pa,
+ const void *pb)
{
+ const char *a = (const char *) pa;
+ const char *b = (const char *) pb;
unsigned int da, db;
const char *p;
@@ -882,12 +920,12 @@ hb_ot_tag_from_language (hb_language_t language)
char tag[4];
int i;
s += 6;
- for (i = 0; i < 4 && ISALPHA (s[i]); i++)
+ for (i = 0; i < 4 && ISALNUM (s[i]); i++)
tag[i] = TOUPPER (s[i]);
if (i) {
for (; i < 4; i++)
tag[i] = ' ';
- return HB_TAG_CHAR4 (tag);
+ return HB_TAG (tag[0], tag[1], tag[2], tag[3]);
}
}
@@ -907,12 +945,36 @@ hb_ot_tag_from_language (hb_language_t language)
return HB_TAG('A','P','P','H'); /* Phonetic transcription—Americanist conventions */
}
+ /*
+ * "Syre" is a BCP-47 script tag, meaning the Estrangela variant of the Syriac script.
+ * It can be applied to any language.
+ */
+ if (strstr (lang_str, "-syre")) {
+ return HB_TAG('S','Y','R','E'); /* Estrangela Syriac */
+ }
+
+ /*
+ * "Syrj" is a BCP-47 script tag, meaning the Western variant of the Syriac script.
+ * It can be applied to any language.
+ */
+ if (strstr (lang_str, "-syrj")) {
+ return HB_TAG('S','Y','R','J'); /* Western Syriac */
+ }
+
+ /*
+ * "Syrn" is a BCP-47 script tag, meaning the Eastern variant of the Syriac script.
+ * It can be applied to any language.
+ */
+ if (strstr (lang_str, "-syrn")) {
+ return HB_TAG('S','Y','R','N'); /* Eastern Syriac */
+ }
+
/* Find a language matching in the first component */
{
const LangTag *lang_tag;
lang_tag = (LangTag *) bsearch (lang_str, ot_languages,
ARRAY_LENGTH (ot_languages), sizeof (LangTag),
- (hb_compare_func_t) lang_compare_first_component);
+ lang_compare_first_component);
if (lang_tag)
return lang_tag->tag;
}
@@ -960,7 +1022,23 @@ hb_ot_tag_to_language (hb_tag_t tag)
unsigned int i;
if (tag == HB_OT_TAG_DEFAULT_LANGUAGE)
- return NULL;
+ return nullptr;
+
+ /* struct LangTag has only room for 3-letter language tags. */
+ switch (tag) {
+ case HB_TAG('A','P','P','H'): /* Phonetic transcription—Americanist conventions */
+ return hb_language_from_string ("und-fonnapa", -1);
+ case HB_TAG('I','P','P','H'): /* Phonetic transcription—IPA conventions */
+ return hb_language_from_string ("und-fonipa", -1);
+ case HB_TAG('S','Y','R',' '): /* Syriac [macrolanguage] */
+ return hb_language_from_string ("syr", -1);
+ case HB_TAG('S','Y','R','E'): /* Estrangela Syriac */
+ return hb_language_from_string ("und-Syre", -1);
+ case HB_TAG('S','Y','R','J'): /* Western Syriac */
+ return hb_language_from_string ("und-Syrj", -1);
+ case HB_TAG('S','Y','R','N'): /* Eastern Syriac */
+ return hb_language_from_string ("und-Syrn", -1);
+ }
for (i = 0; i < ARRAY_LENGTH (ot_languages); i++)
if (ot_languages[i].tag == tag)
@@ -976,14 +1054,6 @@ hb_ot_tag_to_language (hb_tag_t tag)
}
}
- /* struct LangTag has only room for 3-letter language tags. */
- switch (tag) {
- case HB_TAG('A','P','P','H'): /* Phonetic transcription—Americanist conventions */
- return hb_language_from_string ("und-fonnapa", -1);
- case HB_TAG('I','P','P','H'): /* Phonetic transcription—IPA conventions */
- return hb_language_from_string ("und-fonipa", -1);
- }
-
/* Else return a custom language in the form of "x-hbotABCD" */
{
unsigned char buf[11] = "x-hbot";
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-avar-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-avar-table.hh
new file mode 100644
index 0000000000..4b88a40304
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-avar-table.hh
@@ -0,0 +1,149 @@
+/*
+ * 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"
+
+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);
+};
+
+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 < 2)
+ {
+ if (!len)
+ return value;
+ else /* len == 1*/
+ return value - array[0].fromCoord + array[0].toCoord;
+ }
+
+ 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
+ */
+
+#define HB_OT_TAG_avar HB_TAG('a','v','a','r')
+
+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);
+ }
+
+ 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 */
+ UINT16 reserved; /* This field is permanently reserved. Set to 0. */
+ UINT16 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 */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-fvar-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-fvar-table.hh
new file mode 100644
index 0000000000..2a9357a5e2
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-fvar-table.hh
@@ -0,0 +1,209 @@
+/*
+ * 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_FVAR_TABLE_HH
+#define HB_OT_VAR_FVAR_TABLE_HH
+
+#include "hb-open-type-private.hh"
+
+namespace OT {
+
+
+struct InstanceRecord
+{
+ inline bool sanitize (hb_sanitize_context_t *c, unsigned int axis_count) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ c->check_array (coordinates, coordinates[0].static_size, axis_count));
+ }
+
+ protected:
+ UINT16 subfamilyNameID;/* The name ID for entries in the 'name' table
+ * that provide subfamily names for this instance. */
+ UINT16 reserved; /* Reserved for future use — set to 0. */
+ Fixed coordinates[VAR];/* The coordinates array for this instance. */
+ //UINT16 postScriptNameIDX;/*Optional. The name ID for entries in the 'name'
+ // * table that provide PostScript names for this
+ // * instance. */
+
+ public:
+ DEFINE_SIZE_ARRAY (4, coordinates);
+};
+
+struct AxisRecord
+{
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this));
+ }
+
+ public:
+ Tag axisTag; /* Tag identifying the design variation for the axis. */
+ Fixed minValue; /* The minimum coordinate value for the axis. */
+ Fixed defaultValue; /* The default coordinate value for the axis. */
+ Fixed maxValue; /* The maximum coordinate value for the axis. */
+ UINT16 reserved; /* Reserved for future use — set to 0. */
+ UINT16 axisNameID; /* The name ID for entries in the 'name' table that
+ * provide a display name for this axis. */
+
+ public:
+ DEFINE_SIZE_STATIC (20);
+};
+
+
+/*
+ * fvar — Font Variations Table
+ */
+
+#define HB_OT_TAG_fvar HB_TAG('f','v','a','r')
+
+struct fvar
+{
+ static const hb_tag_t tableTag = HB_OT_TAG_fvar;
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (version.sanitize (c) &&
+ likely (version.major == 1) &&
+ c->check_struct (this) &&
+ instanceSize >= axisCount * 4 + 4 &&
+ axisSize <= 1024 && /* Arbitrary, just to simplify overflow checks. */
+ instanceSize <= 1024 && /* Arbitrary, just to simplify overflow checks. */
+ c->check_range (this, things) &&
+ c->check_range (&StructAtOffset<char> (this, things),
+ axisCount * axisSize + instanceCount * instanceSize));
+ }
+
+ inline unsigned int get_axis_count (void) const
+ { return axisCount; }
+
+ inline bool get_axis (unsigned int index, hb_ot_var_axis_t *info) const
+ {
+ if (unlikely (index >= axisCount))
+ return false;
+
+ if (info)
+ {
+ const AxisRecord &axis = get_axes ()[index];
+ info->tag = axis.axisTag;
+ info->name_id = axis.axisNameID;
+ info->default_value = axis.defaultValue / 65536.;
+ /* Ensure order, to simplify client math. */
+ info->min_value = MIN<float> (info->default_value, axis.minValue / 65536.);
+ info->max_value = MAX<float> (info->default_value, axis.maxValue / 65536.);
+ }
+
+ return true;
+ }
+
+ inline unsigned int get_axis_infos (unsigned int start_offset,
+ unsigned int *axes_count /* IN/OUT */,
+ hb_ot_var_axis_t *axes_array /* OUT */) const
+ {
+ if (axes_count)
+ {
+ unsigned int count = axisCount;
+ start_offset = MIN (start_offset, count);
+
+ count -= start_offset;
+ axes_array += start_offset;
+
+ count = MIN (count, *axes_count);
+ *axes_count = count;
+
+ for (unsigned int i = 0; i < count; i++)
+ get_axis (start_offset + i, axes_array + i);
+ }
+ return axisCount;
+ }
+
+ inline bool find_axis (hb_tag_t tag, unsigned int *index, hb_ot_var_axis_t *info) const
+ {
+ const AxisRecord *axes = get_axes ();
+ unsigned int count = get_axis_count ();
+ for (unsigned int i = 0; i < count; i++)
+ if (axes[i].axisTag == tag)
+ {
+ if (index)
+ *index = i;
+ return get_axis (i, info);
+ }
+ if (index)
+ *index = HB_OT_VAR_NO_AXIS_INDEX;
+ return false;
+ }
+
+ inline int normalize_axis_value (unsigned int axis_index, float v) const
+ {
+ hb_ot_var_axis_t axis;
+ if (!get_axis (axis_index, &axis))
+ return 0;
+
+ v = MAX (MIN (v, axis.max_value), axis.min_value); /* Clamp. */
+
+ if (v == axis.default_value)
+ return 0;
+ else if (v < axis.default_value)
+ v = (v - axis.default_value) / (axis.default_value - axis.min_value);
+ else
+ v = (v - axis.default_value) / (axis.max_value - axis.default_value);
+ return (int) (v * 16384. + (v >= 0. ? .5 : -.5));
+ }
+
+ protected:
+ inline const AxisRecord * get_axes (void) const
+ { return &StructAtOffset<AxisRecord> (this, things); }
+
+ inline const InstanceRecord * get_instances (void) const
+ { return &StructAtOffset<InstanceRecord> (get_axes () + axisCount, 0); }
+
+ protected:
+ FixedVersion<>version; /* Version of the fvar table
+ * initially set to 0x00010000u */
+ Offset16 things; /* Offset in bytes from the beginning of the table
+ * to the start of the AxisRecord array. */
+ UINT16 reserved; /* This field is permanently reserved. Set to 2. */
+ UINT16 axisCount; /* The number of variation axes in the font (the
+ * number of records in the axes array). */
+ UINT16 axisSize; /* The size in bytes of each VariationAxisRecord —
+ * set to 20 (0x0014) for this version. */
+ UINT16 instanceCount; /* The number of named instances defined in the font
+ * (the number of records in the instances array). */
+ UINT16 instanceSize; /* The size in bytes of each InstanceRecord — set
+ * to either axisCount * sizeof(Fixed) + 4, or to
+ * axisCount * sizeof(Fixed) + 6. */
+
+ public:
+ DEFINE_SIZE_STATIC (16);
+};
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_VAR_FVAR_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-hvar-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-hvar-table.hh
new file mode 100644
index 0000000000..fac843a719
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-hvar-table.hh
@@ -0,0 +1,165 @@
+/*
+ * 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_HVAR_TABLE_HH
+#define HB_OT_VAR_HVAR_TABLE_HH
+
+#include "hb-ot-layout-common-private.hh"
+
+
+namespace OT {
+
+
+struct DeltaSetIndexMap
+{
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ c->check_array (mapData, get_width (), mapCount));
+ }
+
+ unsigned int map (unsigned int v) const /* Returns 16.16 outer.inner. */
+ {
+ /* If count is zero, pass value unchanged. This takes
+ * care of direct mapping for advance map. */
+ if (!mapCount)
+ return v;
+
+ if (v >= mapCount)
+ v = mapCount - 1;
+
+ unsigned int u = 0;
+ { /* Fetch it. */
+ unsigned int w = get_width ();
+ const UINT8 *p = mapData + w * v;
+ for (; w; w--)
+ u = (u << 8) + *p++;
+ }
+
+ { /* Repack it. */
+ unsigned int n = get_inner_bitcount ();
+ unsigned int outer = u >> n;
+ unsigned int inner = u & ((1 << n) - 1);
+ u = (outer<<16) | inner;
+ }
+
+ return u;
+ }
+
+ protected:
+ inline unsigned int get_width (void) const
+ { return ((format >> 4) & 3) + 1; }
+
+ inline unsigned int get_inner_bitcount (void) const
+ { return (format & 0xF) + 1; }
+
+ protected:
+ UINT16 format; /* A packed field that describes the compressed
+ * representation of delta-set indices. */
+ UINT16 mapCount; /* The number of mapping entries. */
+ UINT8 mapData[VAR]; /* The delta-set index mapping data. */
+
+ public:
+ DEFINE_SIZE_ARRAY (4, mapData);
+};
+
+
+/*
+ * HVAR -- The Horizontal Metrics Variations Table
+ * VVAR -- The Vertical Metrics Variations Table
+ */
+
+#define HB_OT_TAG_HVAR HB_TAG('H','V','A','R')
+#define HB_OT_TAG_VVAR HB_TAG('V','V','A','R')
+
+struct HVARVVAR
+{
+ static const hb_tag_t HVARTag = HB_OT_TAG_HVAR;
+ static const hb_tag_t VVARTag = HB_OT_TAG_VVAR;
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (version.sanitize (c) &&
+ likely (version.major == 1) &&
+ varStore.sanitize (c, this) &&
+ advMap.sanitize (c, this) &&
+ lsbMap.sanitize (c, this) &&
+ rsbMap.sanitize (c, this));
+ }
+
+ inline float get_advance_var (hb_codepoint_t glyph,
+ int *coords, unsigned int coord_count) const
+ {
+ unsigned int varidx = (this+advMap).map (glyph);
+ return (this+varStore).get_delta (varidx, coords, coord_count);
+ }
+
+ inline bool has_sidebearing_deltas (void) const
+ { return lsbMap && rsbMap; }
+
+ protected:
+ FixedVersion<>version; /* Version of the metrics variation table
+ * initially set to 0x00010000u */
+ LOffsetTo<VariationStore>
+ varStore; /* Offset to item variation store table. */
+ LOffsetTo<DeltaSetIndexMap>
+ advMap; /* Offset to advance var-idx mapping. */
+ LOffsetTo<DeltaSetIndexMap>
+ lsbMap; /* Offset to lsb/tsb var-idx mapping. */
+ LOffsetTo<DeltaSetIndexMap>
+ rsbMap; /* Offset to rsb/bsb var-idx mapping. */
+
+ public:
+ DEFINE_SIZE_STATIC (20);
+};
+
+struct HVAR : HVARVVAR {
+ static const hb_tag_t tableTag = HB_OT_TAG_HVAR;
+};
+struct VVAR : HVARVVAR {
+ static const hb_tag_t tableTag = HB_OT_TAG_VVAR;
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (static_cast<const HVARVVAR *> (this)->sanitize (c) &&
+ vorgMap.sanitize (c, this));
+ }
+
+ protected:
+ LOffsetTo<DeltaSetIndexMap>
+ vorgMap; /* Offset to vertical-origin var-idx mapping. */
+
+ public:
+ DEFINE_SIZE_STATIC (24);
+};
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_VAR_HVAR_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-mvar-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-mvar-table.hh
new file mode 100644
index 0000000000..e17ff5160a
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-mvar-table.hh
@@ -0,0 +1,114 @@
+/*
+ * 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_MVAR_TABLE_HH
+#define HB_OT_VAR_MVAR_TABLE_HH
+
+#include "hb-ot-layout-common-private.hh"
+
+
+namespace OT {
+
+
+struct VariationValueRecord
+{
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this));
+ }
+
+ public:
+ Tag valueTag; /* Four-byte tag identifying a font-wide measure. */
+ UINT32 varIdx; /* Outer/inner index into VariationStore item. */
+
+ public:
+ DEFINE_SIZE_STATIC (8);
+};
+
+
+/*
+ * MVAR -- Metrics Variations Table
+ */
+
+#define HB_OT_TAG_MVAR HB_TAG('M','V','A','R')
+
+struct MVAR
+{
+ static const hb_tag_t tableTag = HB_OT_TAG_MVAR;
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (version.sanitize (c) &&
+ likely (version.major == 1) &&
+ c->check_struct (this) &&
+ valueRecordSize >= VariationValueRecord::static_size &&
+ varStore.sanitize (c, this) &&
+ c->check_array (values, valueRecordSize, valueRecordCount));
+ }
+
+ inline float get_var (hb_tag_t tag,
+ int *coords, unsigned int coord_count) const
+ {
+ const VariationValueRecord *record;
+ record = (VariationValueRecord *) bsearch (&tag, values,
+ valueRecordCount, valueRecordSize,
+ tag_compare);
+ if (!record)
+ return 0.;
+
+ return (this+varStore).get_delta (record->varIdx, coords, coord_count);
+ }
+
+protected:
+ static inline int tag_compare (const void *pa, const void *pb)
+ {
+ const hb_tag_t *a = (const hb_tag_t *) pa;
+ const Tag *b = (const Tag *) pb;
+ return b->cmp (*a);
+ }
+
+ protected:
+ FixedVersion<>version; /* Version of the metrics variation table
+ * initially set to 0x00010000u */
+ UINT16 reserved; /* Not used; set to 0. */
+ UINT16 valueRecordSize;/* The size in bytes of each value record —
+ * must be greater than zero. */
+ UINT16 valueRecordCount;/* The number of value records — may be zero. */
+ OffsetTo<VariationStore>
+ varStore; /* Offset to item variation store table. */
+ UINT8 values[VAR]; /* Array of value records. The records must be
+ * in binary order of their valueTag field. */
+
+ public:
+ DEFINE_SIZE_ARRAY (12, values);
+};
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_VAR_MVAR_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-var.cc
new file mode 100644
index 0000000000..90ba0bd02c
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var.cc
@@ -0,0 +1,159 @@
+/*
+ * 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
+ */
+
+#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-mvar-table.hh"
+#include "hb-ot-var.h"
+
+/*
+ * 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 ());
+}
+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:
+ * @face: #hb_face_t to test
+ *
+ * This function allows to verify the presence of OpenType variation data on the face.
+ * Alternatively, use hb_ot_var_get_axis_count().
+ *
+ * Return value: true if face has a `fvar' table and false otherwise
+ *
+ * Since: 1.4.2
+ **/
+hb_bool_t
+hb_ot_var_has_data (hb_face_t *face)
+{
+ return &_get_fvar (face) != &OT::Null(OT::fvar);
+}
+
+/**
+ * hb_ot_var_get_axis_count:
+ *
+ * Since: 1.4.2
+ **/
+unsigned int
+hb_ot_var_get_axis_count (hb_face_t *face)
+{
+ const OT::fvar &fvar = _get_fvar (face);
+ return fvar.get_axis_count ();
+}
+
+/**
+ * hb_ot_var_get_axes:
+ *
+ * Since: 1.4.2
+ **/
+unsigned int
+hb_ot_var_get_axes (hb_face_t *face,
+ unsigned int start_offset,
+ unsigned int *axes_count /* IN/OUT */,
+ hb_ot_var_axis_t *axes_array /* OUT */)
+{
+ const OT::fvar &fvar = _get_fvar (face);
+ return fvar.get_axis_infos (start_offset, axes_count, axes_array);
+}
+
+/**
+ * hb_ot_var_find_axis:
+ *
+ * Since: 1.4.2
+ **/
+hb_bool_t
+hb_ot_var_find_axis (hb_face_t *face,
+ hb_tag_t axis_tag,
+ unsigned int *axis_index,
+ hb_ot_var_axis_t *axis_info)
+{
+ const OT::fvar &fvar = _get_fvar (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, nullptr) &&
+ axis_index < coords_length)
+ coords[axis_index] = fvar.normalize_axis_value (axis_index, variations[i].value);
+ }
+
+ const OT::avar &avar = _get_avar (face);
+ avar.map_coords (coords, coords_length);
+}
+
+/**
+ * hb_ot_var_normalize_coords:
+ *
+ * Since: 1.4.2
+ **/
+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);
+ for (unsigned int i = 0; i < coords_length; i++)
+ normalized_coords[i] = fvar.normalize_axis_value (i, design_coords[i]);
+
+ const OT::avar &avar = _get_avar (face);
+ avar.map_coords (normalized_coords, coords_length);
+}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-var.h
new file mode 100644
index 0000000000..a2c0c5f2b0
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var.h
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_H_IN
+#error "Include <hb-ot.h> instead."
+#endif
+
+#ifndef HB_OT_VAR_H
+#define HB_OT_VAR_H
+
+#include "hb.h"
+
+HB_BEGIN_DECLS
+
+
+#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
+ */
+
+/**
+ * hb_ot_var_axis_t:
+ *
+ * Since: 1.4.2
+ */
+typedef struct hb_ot_var_axis_t {
+ hb_tag_t tag;
+ unsigned int name_id;
+ float min_value;
+ float default_value;
+ float max_value;
+} hb_ot_var_axis_t;
+
+HB_EXTERN hb_bool_t
+hb_ot_var_has_data (hb_face_t *face);
+
+/**
+ * HB_OT_VAR_NO_AXIS_INDEX:
+ *
+ * Since: 1.4.2
+ */
+#define HB_OT_VAR_NO_AXIS_INDEX 0xFFFFFFFFu
+
+HB_EXTERN unsigned int
+hb_ot_var_get_axis_count (hb_face_t *face);
+
+HB_EXTERN unsigned int
+hb_ot_var_get_axes (hb_face_t *face,
+ unsigned int start_offset,
+ unsigned int *axes_count /* IN/OUT */,
+ hb_ot_var_axis_t *axes_array /* OUT */);
+
+HB_EXTERN hb_bool_t
+hb_ot_var_find_axis (hb_face_t *face,
+ hb_tag_t axis_tag,
+ unsigned int *axis_index,
+ hb_ot_var_axis_t *axis_info);
+
+
+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
+
+#endif /* HB_OT_VAR_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot.h b/src/3rdparty/harfbuzz-ng/src/hb-ot.h
index 113e37b08a..2120a3efa3 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot.h
@@ -35,6 +35,7 @@
#include "hb-ot-math.h"
#include "hb-ot-tag.h"
#include "hb-ot-shape.h"
+#include "hb-ot-var.h"
HB_BEGIN_DECLS
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-private.hh
index 666af6260b..acddd89381 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-private.hh
@@ -44,16 +44,14 @@
#include <stddef.h>
#include <string.h>
#include <assert.h>
-
-/* We only use these two for debug output. However, the debug code is
- * always seen by the compiler (and optimized out in non-debug builds.
- * If including these becomes a problem, we can start thinking about
- * someway around that. */
-#include <stdio.h>
#include <errno.h>
+#include <stdio.h>
#include <stdarg.h>
+#define HB_PASTE1(a,b) a##b
+#define HB_PASTE(a,b) HB_PASTE1(a,b)
+
/* Compile-time custom allocator support. */
#if defined(hb_malloc_impl) \
@@ -74,10 +72,25 @@ extern "C" void hb_free_impl(void *ptr);
/* Compiler attributes */
-#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
-#define _HB_BOOLEAN_EXPR(expr) ((expr) ? 1 : 0)
-#define likely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 1))
-#define unlikely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 0))
+#if __cplusplus < 201103L
+
+#ifndef nullptr
+#define nullptr NULL
+#endif
+
+// Static assertions
+#ifndef static_assert
+#define static_assert(e, msg) \
+ HB_UNUSED typedef int HB_PASTE(static_assertion_failed_at_line_, __LINE__) [(e) ? 1 : -1]
+#endif // static_assert
+
+#endif // __cplusplus < 201103L
+
+#define _GNU_SOURCE 1
+
+#if (defined(__GNUC__) || defined(__clang__)) && defined(__OPTIMIZE__)
+#define likely(expr) (__builtin_expect (!!(expr), 1))
+#define unlikely(expr) (__builtin_expect (!!(expr), 0))
#else
#define likely(expr) (expr)
#define unlikely(expr) (expr)
@@ -99,6 +112,8 @@ extern "C" void hb_free_impl(void *ptr);
#endif
#if __GNUC__ >= 4
#define HB_UNUSED __attribute__((unused))
+#elif defined(_MSC_VER) /* https://github.com/harfbuzz/harfbuzz/issues/635 */
+#define HB_UNUSED __pragma(warning(suppress: 4100 4101))
#else
#define HB_UNUSED
#endif
@@ -168,21 +183,17 @@ extern "C" void hb_free_impl(void *ptr);
# if defined(_WIN32_WCE)
/* Some things not defined on Windows CE. */
-# define strdup _strdup
# define vsnprintf _vsnprintf
-# define getenv(Name) NULL
+# define getenv(Name) nullptr
# if _WIN32_WCE < 0x800
# define setlocale(Category, Locale) "C"
static int errno = 0; /* Use something better? */
# endif
# elif defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
-# define getenv(Name) NULL
+# define getenv(Name) nullptr
# endif
# if defined(_MSC_VER) && _MSC_VER < 1900
# define snprintf _snprintf
-# elif defined(_MSC_VER) && _MSC_VER >= 1900
-# /* Covers VC++ Error for strdup being a deprecated POSIX name and to instead use _strdup instead */
-# define strdup _strdup
# endif
#endif
@@ -214,11 +225,6 @@ static int errno = 0; /* Use something better? */
/* Basics */
-
-#ifndef NULL
-# define NULL ((void *) 0)
-#endif
-
#undef MIN
template <typename Type>
static inline Type MIN (const Type &a, const Type &b) { return a < b ? a : b; }
@@ -240,32 +246,26 @@ static inline unsigned int ARRAY_LENGTH (const Type (&)[n]) { return n; }
#define HB_STMT_START do
#define HB_STMT_END while (0)
-#define _ASSERT_STATIC1(_line, _cond) HB_UNUSED typedef int _static_assert_on_line_##_line##_failed[(_cond)?1:-1]
-#define _ASSERT_STATIC0(_line, _cond) _ASSERT_STATIC1 (_line, (_cond))
-#define ASSERT_STATIC(_cond) _ASSERT_STATIC0 (__LINE__, (_cond))
-
-template <unsigned int cond> class hb_assert_constant_t {};
+template <unsigned int cond> class hb_assert_constant_t;
+template <> class hb_assert_constant_t<1> {};
#define ASSERT_STATIC_EXPR_ZERO(_cond) (0 * (unsigned int) sizeof (hb_assert_constant_t<_cond>))
-#define _PASTE1(a,b) a##b
-#define PASTE(a,b) _PASTE1(a,b)
-
/* Lets assert int types. Saves trouble down the road. */
-ASSERT_STATIC (sizeof (int8_t) == 1);
-ASSERT_STATIC (sizeof (uint8_t) == 1);
-ASSERT_STATIC (sizeof (int16_t) == 2);
-ASSERT_STATIC (sizeof (uint16_t) == 2);
-ASSERT_STATIC (sizeof (int32_t) == 4);
-ASSERT_STATIC (sizeof (uint32_t) == 4);
-ASSERT_STATIC (sizeof (int64_t) == 8);
-ASSERT_STATIC (sizeof (uint64_t) == 8);
+static_assert ((sizeof (int8_t) == 1), "");
+static_assert ((sizeof (uint8_t) == 1), "");
+static_assert ((sizeof (int16_t) == 2), "");
+static_assert ((sizeof (uint16_t) == 2), "");
+static_assert ((sizeof (int32_t) == 4), "");
+static_assert ((sizeof (uint32_t) == 4), "");
+static_assert ((sizeof (int64_t) == 8), "");
+static_assert ((sizeof (uint64_t) == 8), "");
-ASSERT_STATIC (sizeof (hb_codepoint_t) == 4);
-ASSERT_STATIC (sizeof (hb_position_t) == 4);
-ASSERT_STATIC (sizeof (hb_mask_t) == 4);
-ASSERT_STATIC (sizeof (hb_var_int_t) == 4);
+static_assert ((sizeof (hb_codepoint_t) == 4), "");
+static_assert ((sizeof (hb_position_t) == 4), "");
+static_assert ((sizeof (hb_mask_t) == 4), "");
+static_assert ((sizeof (hb_var_int_t) == 4), "");
/* We like our types POD */
@@ -300,7 +300,7 @@ ASSERT_STATIC (sizeof (hb_var_int_t) == 4);
/* Void! */
struct _hb_void_t {};
typedef const _hb_void_t *hb_void_t;
-#define HB_VOID ((const _hb_void_t *) NULL)
+#define HB_VOID ((const _hb_void_t *) nullptr)
/* Return the number of 1 bits in mask. */
static inline HB_CONST_FUNC unsigned int
@@ -316,6 +316,18 @@ _hb_popcount32 (uint32_t mask)
return (((y + (y >> 3)) & 030707070707) % 077);
#endif
}
+static inline HB_CONST_FUNC unsigned int
+_hb_popcount64 (uint64_t mask)
+{
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+ if (sizeof (long) >= sizeof (mask))
+ return __builtin_popcountl (mask);
+#endif
+ return _hb_popcount32 (mask & 0xFFFFFFFF) + _hb_popcount32 (mask >> 32);
+}
+template <typename T> static inline unsigned int _hb_popcount (T mask);
+template <> inline unsigned int _hb_popcount<uint32_t> (uint32_t mask) { return _hb_popcount32 (mask); }
+template <> inline unsigned int _hb_popcount<uint64_t> (uint64_t mask) { return _hb_popcount64 (mask); }
/* Returns the number of bits needed to store number */
static inline HB_CONST_FUNC unsigned int
@@ -357,16 +369,11 @@ _hb_unsigned_int_mul_overflows (unsigned int count, unsigned int size)
}
-/* Type of bsearch() / qsort() compare function */
-typedef int (*hb_compare_func_t) (const void *, const void *);
-
-
-
/* arrays and maps */
-#define HB_PREALLOCED_ARRAY_INIT {0, 0, NULL}
+#define HB_PREALLOCED_ARRAY_INIT {0, 0, nullptr}
template <typename Type, unsigned int StaticSize=16>
struct hb_prealloced_array_t
{
@@ -375,41 +382,56 @@ struct hb_prealloced_array_t
Type *array;
Type static_array[StaticSize];
- void init (void) { memset (this, 0, sizeof (*this)); }
+ void init (void)
+ {
+ len = 0;
+ allocated = ARRAY_LENGTH (static_array);
+ array = static_array;
+ }
inline Type& operator [] (unsigned int i) { return array[i]; }
inline const Type& operator [] (unsigned int i) const { return array[i]; }
inline Type *push (void)
{
- if (!array) {
- array = static_array;
- allocated = ARRAY_LENGTH (static_array);
- }
- if (likely (len < allocated))
- return &array[len++];
+ if (unlikely (!resize (len + 1)))
+ return nullptr;
- /* Need to reallocate */
- unsigned int new_allocated = allocated + (allocated >> 1) + 8;
- Type *new_array = NULL;
+ return &array[len - 1];
+ }
- if (array == static_array) {
- new_array = (Type *) calloc (new_allocated, sizeof (Type));
- if (new_array)
- memcpy (new_array, array, len * sizeof (Type));
- } else {
- bool overflows = (new_allocated < allocated) || _hb_unsigned_int_mul_overflows (new_allocated, sizeof (Type));
- if (likely (!overflows)) {
- new_array = (Type *) realloc (array, new_allocated * sizeof (Type));
+ inline bool resize (unsigned int size)
+ {
+ if (unlikely (size > allocated))
+ {
+ /* Need to reallocate */
+
+ unsigned int new_allocated = allocated;
+ while (size >= new_allocated)
+ new_allocated += (new_allocated >> 1) + 8;
+
+ Type *new_array = nullptr;
+
+ if (array == static_array) {
+ new_array = (Type *) calloc (new_allocated, sizeof (Type));
+ if (new_array)
+ memcpy (new_array, array, len * sizeof (Type));
+ } else {
+ bool overflows = (new_allocated < allocated) || _hb_unsigned_int_mul_overflows (new_allocated, sizeof (Type));
+ if (likely (!overflows)) {
+ new_array = (Type *) realloc (array, new_allocated * sizeof (Type));
+ }
}
- }
- if (unlikely (!new_array))
- return NULL;
+ if (unlikely (!new_array))
+ return false;
+
+ array = new_array;
+ allocated = new_allocated;
+ }
- array = new_array;
- allocated = new_allocated;
- return &array[len++];
+ len = size;
+ return true;
}
inline void pop (void)
@@ -438,42 +460,67 @@ struct hb_prealloced_array_t
for (unsigned int i = 0; i < len; i++)
if (array[i] == v)
return &array[i];
- return NULL;
+ return nullptr;
}
template <typename T>
inline const Type *find (T v) const {
for (unsigned int i = 0; i < len; i++)
if (array[i] == v)
return &array[i];
- return NULL;
+ return nullptr;
}
inline void qsort (void)
{
- ::qsort (array, len, sizeof (Type), (hb_compare_func_t) Type::cmp);
+ ::qsort (array, len, sizeof (Type), Type::cmp);
}
inline void qsort (unsigned int start, unsigned int end)
{
- ::qsort (array + start, end - start, sizeof (Type), (hb_compare_func_t) Type::cmp);
+ ::qsort (array + start, end - start, sizeof (Type), Type::cmp);
}
template <typename T>
- inline Type *bsearch (T *key)
+ inline Type *bsearch (T *x)
{
- return (Type *) ::bsearch (key, array, len, sizeof (Type), (hb_compare_func_t) Type::cmp);
+ unsigned int i;
+ return bfind (x, &i) ? &array[i] : nullptr;
}
template <typename T>
- inline const Type *bsearch (T *key) const
+ inline const Type *bsearch (T *x) const
{
- return (const Type *) ::bsearch (key, array, len, sizeof (Type), (hb_compare_func_t) Type::cmp);
+ unsigned int i;
+ return bfind (x, &i) ? &array[i] : nullptr;
+ }
+ template <typename T>
+ inline bool bfind (T *x, unsigned int *i) const
+ {
+ 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
+ {
+ *i = mid;
+ return true;
+ }
+ }
+ if (max < 0 || (max < (int) this->len && this->array[max].cmp (x) > 0))
+ max++;
+ *i = max;
+ return false;
}
inline void finish (void)
{
if (array != static_array)
free (array);
- array = NULL;
+ array = nullptr;
allocated = len = 0;
}
};
@@ -490,7 +537,7 @@ struct hb_auto_array_t : hb_prealloced_array_t <Type>
template <typename item_t, typename lock_t>
struct hb_lockable_set_t
{
- hb_prealloced_array_t <item_t, 2> items;
+ hb_prealloced_array_t <item_t, 1> items;
inline void init (void) { items.init (); }
@@ -507,7 +554,7 @@ struct hb_lockable_set_t
old.finish ();
}
else {
- item = NULL;
+ item = nullptr;
l.unlock ();
}
} else {
@@ -595,22 +642,6 @@ static inline unsigned char TOUPPER (unsigned char c)
static inline unsigned char TOLOWER (unsigned char c)
{ return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; }
-#define HB_TAG_CHAR4(s) (HB_TAG(((const char *) s)[0], \
- ((const char *) s)[1], \
- ((const char *) s)[2], \
- ((const char *) s)[3]))
-
-
-/* C++ helpers */
-
-/* Makes class uncopyable. Use in private: section. */
-#define NO_COPY(T) \
- T (const T &o); \
- T &operator = (const T &o)
-
-
-/* Debug */
-
/* HB_NDEBUG disables some sanity checks that are very safe to disable and
* should be disabled in production systems. If NDEBUG is defined, enable
@@ -621,255 +652,6 @@ static inline unsigned char TOLOWER (unsigned char c)
#define HB_NDEBUG
#endif
-#ifndef HB_DEBUG
-#define HB_DEBUG 0
-#endif
-
-static inline bool
-_hb_debug (unsigned int level,
- unsigned int max_level)
-{
- return level < max_level;
-}
-
-#define DEBUG_LEVEL_ENABLED(WHAT, LEVEL) (_hb_debug ((LEVEL), HB_DEBUG_##WHAT))
-#define DEBUG_ENABLED(WHAT) (DEBUG_LEVEL_ENABLED (WHAT, 0))
-
-static inline void
-_hb_print_func (const char *func)
-{
- if (func)
- {
- unsigned int func_len = strlen (func);
- /* Skip "static" */
- if (0 == strncmp (func, "static ", 7))
- func += 7;
- /* Skip "typename" */
- if (0 == strncmp (func, "typename ", 9))
- func += 9;
- /* Skip return type */
- const char *space = strchr (func, ' ');
- if (space)
- func = space + 1;
- /* Skip parameter list */
- const char *paren = strchr (func, '(');
- if (paren)
- func_len = paren - func;
- fprintf (stderr, "%.*s", func_len, func);
- }
-}
-
-template <int max_level> static inline void
-_hb_debug_msg_va (const char *what,
- const void *obj,
- const char *func,
- bool indented,
- unsigned int level,
- int level_dir,
- const char *message,
- va_list ap) HB_PRINTF_FUNC(7, 0);
-template <int max_level> static inline void
-_hb_debug_msg_va (const char *what,
- const void *obj,
- const char *func,
- bool indented,
- unsigned int level,
- int level_dir,
- const char *message,
- va_list ap)
-{
- if (!_hb_debug (level, max_level))
- return;
-
- fprintf (stderr, "%-10s", what ? what : "");
-
- if (obj)
- fprintf (stderr, "(%0*lx) ", (unsigned int) (2 * sizeof (void *)), (unsigned long) obj);
- else
- fprintf (stderr, " %*s ", (unsigned int) (2 * sizeof (void *)), "");
-
- if (indented) {
-#define VBAR "\342\224\202" /* U+2502 BOX DRAWINGS LIGHT VERTICAL */
-#define VRBAR "\342\224\234" /* U+251C BOX DRAWINGS LIGHT VERTICAL AND RIGHT */
-#define DLBAR "\342\225\256" /* U+256E BOX DRAWINGS LIGHT ARC DOWN AND LEFT */
-#define ULBAR "\342\225\257" /* U+256F BOX DRAWINGS LIGHT ARC UP AND LEFT */
-#define LBAR "\342\225\264" /* U+2574 BOX DRAWINGS LIGHT LEFT */
- static const char bars[] =
- VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR
- VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR
- VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR
- VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR
- VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR;
- fprintf (stderr, "%2u %s" VRBAR "%s",
- level,
- bars + sizeof (bars) - 1 - MIN ((unsigned int) sizeof (bars) - 1, (unsigned int) (sizeof (VBAR) - 1) * level),
- level_dir ? (level_dir > 0 ? DLBAR : ULBAR) : LBAR);
- } else
- fprintf (stderr, " " VRBAR LBAR);
-
- _hb_print_func (func);
-
- if (message)
- {
- fprintf (stderr, ": ");
- vfprintf (stderr, message, ap);
- }
-
- fprintf (stderr, "\n");
-}
-template <> inline void
-_hb_debug_msg_va<0> (const char *what HB_UNUSED,
- const void *obj HB_UNUSED,
- const char *func HB_UNUSED,
- bool indented HB_UNUSED,
- unsigned int level HB_UNUSED,
- int level_dir HB_UNUSED,
- const char *message HB_UNUSED,
- va_list ap HB_UNUSED) {}
-
-template <int max_level> static inline void
-_hb_debug_msg (const char *what,
- const void *obj,
- const char *func,
- bool indented,
- unsigned int level,
- int level_dir,
- const char *message,
- ...) HB_PRINTF_FUNC(7, 8);
-template <int max_level> static inline void
-_hb_debug_msg (const char *what,
- const void *obj,
- const char *func,
- bool indented,
- unsigned int level,
- int level_dir,
- const char *message,
- ...)
-{
- va_list ap;
- va_start (ap, message);
- _hb_debug_msg_va<max_level> (what, obj, func, indented, level, level_dir, message, ap);
- va_end (ap);
-}
-template <> inline void
-_hb_debug_msg<0> (const char *what HB_UNUSED,
- const void *obj HB_UNUSED,
- const char *func HB_UNUSED,
- bool indented HB_UNUSED,
- unsigned int level HB_UNUSED,
- int level_dir HB_UNUSED,
- const char *message HB_UNUSED,
- ...) HB_PRINTF_FUNC(7, 8);
-template <> inline void
-_hb_debug_msg<0> (const char *what HB_UNUSED,
- const void *obj HB_UNUSED,
- const char *func HB_UNUSED,
- bool indented HB_UNUSED,
- unsigned int level HB_UNUSED,
- int level_dir HB_UNUSED,
- const char *message HB_UNUSED,
- ...) {}
-
-#define DEBUG_MSG_LEVEL(WHAT, OBJ, LEVEL, LEVEL_DIR, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), NULL, true, (LEVEL), (LEVEL_DIR), __VA_ARGS__)
-#define DEBUG_MSG(WHAT, OBJ, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), NULL, false, 0, 0, __VA_ARGS__)
-#define DEBUG_MSG_FUNC(WHAT, OBJ, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), HB_FUNC, false, 0, 0, __VA_ARGS__)
-
-
-/*
- * Printer
- */
-
-template <typename T>
-struct hb_printer_t {
- const char *print (const T&) { return "something"; }
-};
-
-template <>
-struct hb_printer_t<bool> {
- const char *print (bool v) { return v ? "true" : "false"; }
-};
-
-template <>
-struct hb_printer_t<hb_void_t> {
- const char *print (hb_void_t) { return ""; }
-};
-
-
-/*
- * Trace
- */
-
-template <typename T>
-static inline void _hb_warn_no_return (bool returned)
-{
- if (unlikely (!returned)) {
- fprintf (stderr, "OUCH, returned with no call to return_trace(). This is a bug, please report.\n");
- }
-}
-template <>
-/*static*/ inline void _hb_warn_no_return<hb_void_t> (bool returned HB_UNUSED)
-{}
-
-template <int max_level, typename ret_t>
-struct hb_auto_trace_t {
- explicit inline hb_auto_trace_t (unsigned int *plevel_,
- const char *what_,
- const void *obj_,
- const char *func,
- const char *message,
- ...) : plevel (plevel_), what (what_), obj (obj_), returned (false)
- {
- if (plevel) ++*plevel;
-
- va_list ap;
- va_start (ap, message);
- _hb_debug_msg_va<max_level> (what, obj, func, true, plevel ? *plevel : 0, +1, message, ap);
- va_end (ap);
- }
- inline ~hb_auto_trace_t (void)
- {
- _hb_warn_no_return<ret_t> (returned);
- if (!returned) {
- _hb_debug_msg<max_level> (what, obj, NULL, true, plevel ? *plevel : 1, -1, " ");
- }
- if (plevel) --*plevel;
- }
-
- inline ret_t ret (ret_t v, unsigned int line = 0)
- {
- if (unlikely (returned)) {
- fprintf (stderr, "OUCH, double calls to return_trace(). This is a bug, please report.\n");
- return v;
- }
-
- _hb_debug_msg<max_level> (what, obj, NULL, true, plevel ? *plevel : 1, -1,
- "return %s (line %d)",
- hb_printer_t<ret_t>().print (v), line);
- if (plevel) --*plevel;
- plevel = NULL;
- returned = true;
- return v;
- }
-
- private:
- unsigned int *plevel;
- const char *what;
- const void *obj;
- bool returned;
-};
-template <typename ret_t> /* Optimize when tracing is disabled */
-struct hb_auto_trace_t<0, ret_t> {
- explicit inline hb_auto_trace_t (unsigned int *plevel_ HB_UNUSED,
- const char *what HB_UNUSED,
- const void *obj HB_UNUSED,
- const char *func HB_UNUSED,
- const char *message HB_UNUSED,
- ...) {}
-
- inline ret_t ret (ret_t v, unsigned int line HB_UNUSED = 0) { return v; }
-};
-
-#define return_trace(RET) return trace.ret (RET, __LINE__)
/* Misc */
@@ -887,7 +669,7 @@ hb_in_range (T u, T lo, T hi)
* one right now. Declaring a variable won't work as HB_UNUSED
* is unusable on some platforms and unused types are less likely
* to generate a warning than unused variables. */
- ASSERT_STATIC (sizeof (hb_assert_unsigned_t<T>) >= 0);
+ static_assert ((sizeof (hb_assert_unsigned_t<T>) >= 0), "");
/* The casts below are important as if T is smaller than int,
* the subtract results will become a signed int! */
@@ -912,7 +694,7 @@ hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3)
* one enum to another... So this doesn't provide the type-checking that I
* originally had in mind... :(.
*
- * For MSVC warnings, see: https://github.com/behdad/harfbuzz/pull/163
+ * For MSVC warnings, see: https://github.com/harfbuzz/harfbuzz/pull/163
*/
#ifdef _MSC_VER
# pragma warning(disable:4200)
@@ -932,11 +714,10 @@ hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3)
/* Useful for set-operations on small enums.
* For example, for testing "x ∈ {x1, x2, x3}" use:
- * (FLAG_SAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3)))
+ * (FLAG_UNSAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3)))
*/
-#define FLAG(x) (ASSERT_STATIC_EXPR_ZERO ((x) < 32) + (1U << (x)))
-#define FLAG_SAFE(x) (1U << (x))
-#define FLAG_UNSAFE(x) ((x) < 32 ? FLAG_SAFE(x) : 0)
+#define FLAG(x) (ASSERT_STATIC_EXPR_ZERO ((unsigned int)(x) < 32) + (1U << (unsigned int)(x)))
+#define FLAG_UNSAFE(x) ((unsigned int)(x) < 32 ? (1U << (unsigned int)(x)) : 0)
#define FLAG_RANGE(x,y) (ASSERT_STATIC_EXPR_ZERO ((x) < (y)) + FLAG(y+1) - FLAG(x))
@@ -968,7 +749,7 @@ hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *),
template <typename T> static inline void
hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *))
{
- hb_stable_sort (array, len, compar, (int *) NULL);
+ hb_stable_sort (array, len, compar, (int *) nullptr);
}
static inline hb_bool_t
@@ -990,6 +771,73 @@ hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *o
}
+/* Vectorization */
+
+struct HbOpOr
+{
+ static const bool passthru_left = true;
+ static const bool passthru_right = true;
+ template <typename T> static void process (T &o, const T &a, const T &b) { o = a | b; }
+};
+struct HbOpAnd
+{
+ static const bool passthru_left = false;
+ static const bool passthru_right = false;
+ template <typename T> static void process (T &o, const T &a, const T &b) { o = a & b; }
+};
+struct HbOpMinus
+{
+ static const bool passthru_left = true;
+ static const bool passthru_right = false;
+ template <typename T> static void process (T &o, const T &a, const T &b) { o = a & ~b; }
+};
+struct HbOpXor
+{
+ static const bool passthru_left = true;
+ static const bool passthru_right = true;
+ template <typename T> static void process (T &o, const T &a, const T &b) { o = a ^ b; }
+};
+
+/* Type behaving similar to vectorized vars defined using __attribute__((vector_size(...))). */
+template <typename elt_t, unsigned int byte_size>
+struct hb_vector_size_t
+{
+ elt_t& operator [] (unsigned int i) { return v[i]; }
+ const elt_t& operator [] (unsigned int i) const { return v[i]; }
+
+ template <class Op>
+ inline hb_vector_size_t process (const hb_vector_size_t &o) const
+ {
+ hb_vector_size_t r;
+ for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
+ Op::process (r.v[i], v[i], o.v[i]);
+ return r;
+ }
+ inline hb_vector_size_t operator | (const hb_vector_size_t &o) const
+ { return process<HbOpOr> (o); }
+ inline hb_vector_size_t operator & (const hb_vector_size_t &o) const
+ { return process<HbOpAnd> (o); }
+ inline hb_vector_size_t operator ^ (const hb_vector_size_t &o) const
+ { return process<HbOpXor> (o); }
+ inline hb_vector_size_t operator ~ () const
+ {
+ hb_vector_size_t r;
+ for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
+ r.v[i] = ~v[i];
+ return r;
+ }
+
+ private:
+ static_assert (byte_size / sizeof (elt_t) * sizeof (elt_t) == byte_size, "");
+ elt_t v[byte_size / sizeof (elt_t)];
+};
+
+/* The `vector_size' attribute was introduced in gcc 3.1. */
+#if defined( __GNUC__ ) && ( __GNUC__ >= 4 )
+#define HAVE_VECTOR_SIZE 1
+#endif
+
+
/* Global runtime options. */
struct hb_options_t
@@ -1002,7 +850,7 @@ union hb_options_union_t {
unsigned int i;
hb_options_t opts;
};
-ASSERT_STATIC (sizeof (int) == sizeof (hb_options_union_t));
+static_assert ((sizeof (int) == sizeof (hb_options_union_t)), "");
HB_INTERNAL void
_hb_options_init (void);
@@ -1021,4 +869,31 @@ hb_options (void)
/* Size signifying variable-sized array */
#define VAR 1
+
+/* String type. */
+
+struct hb_string_t
+{
+ inline hb_string_t (void) : bytes (nullptr), len (0) {}
+ inline hb_string_t (const char *bytes_, unsigned int len_) : bytes (bytes_), len (len_) {}
+
+ inline int cmp (const hb_string_t &a) const
+ {
+ if (len != a.len)
+ return (int) a.len - (int) len;
+
+ return memcmp (a.bytes, bytes, len);
+ }
+ static inline int cmp (const void *pa, const void *pb)
+ {
+ hb_string_t *a = (hb_string_t *) pa;
+ hb_string_t *b = (hb_string_t *) pb;
+ return b->cmp (*a);
+ }
+
+ const char *bytes;
+ unsigned int len;
+};
+
+
#endif /* HB_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-set-digest-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-set-digest-private.hh
new file mode 100644
index 0000000000..e099a82641
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-set-digest-private.hh
@@ -0,0 +1,179 @@
+/*
+ * Copyright © 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_SET_DIGEST_PRIVATE_HH
+#define HB_SET_DIGEST_PRIVATE_HH
+
+#include "hb-private.hh"
+
+/*
+ * 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.
+ *
+ * Our filters are highly accurate if the lookup covers fairly local
+ * set of glyphs, but fully flooded and ineffective if coverage is
+ * all over the place.
+ *
+ * The frozen-set can be used instead of a digest, to trade more
+ * memory for 100% accuracy, but in practice, that doesn't look like
+ * an attractive trade-off.
+ */
+
+template <typename mask_t, unsigned int shift>
+struct hb_set_digest_lowest_bits_t
+{
+ ASSERT_POD ();
+
+ 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;
+
+ static_assert ((shift < sizeof (hb_codepoint_t) * 8), "");
+ static_assert ((shift + num_bits <= sizeof (hb_codepoint_t) * 8), "");
+
+ inline void init (void) {
+ mask = 0;
+ }
+
+ inline void add (hb_codepoint_t g) {
+ mask |= mask_for (g);
+ }
+
+ inline bool add_range (hb_codepoint_t a, hb_codepoint_t b) {
+ if ((b >> shift) - (a >> shift) >= mask_bits - 1)
+ mask = (mask_t) -1;
+ else {
+ mask_t ma = mask_for (a);
+ mask_t mb = mask_for (b);
+ mask |= mb + (mb - ma) - (mb < ma);
+ }
+ return true;
+ }
+
+ template <typename T>
+ inline void add_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
+ {
+ for (unsigned int i = 0; i < count; i++)
+ {
+ add (*array);
+ array = (const T *) (stride + (const char *) array);
+ }
+ }
+ template <typename T>
+ inline bool add_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
+ {
+ for (unsigned int i = 0; i < count; i++)
+ {
+ add (*array);
+ array = (const T *) (stride + (const char *) array);
+ }
+ return true;
+ }
+
+ inline bool may_have (hb_codepoint_t g) const {
+ return !!(mask & mask_for (g));
+ }
+
+ private:
+
+ static inline mask_t mask_for (hb_codepoint_t g) {
+ return ((mask_t) 1) << ((g >> shift) & (mask_bits - 1));
+ }
+ mask_t mask;
+};
+
+template <typename head_t, typename tail_t>
+struct hb_set_digest_combiner_t
+{
+ ASSERT_POD ();
+
+ inline void init (void) {
+ head.init ();
+ tail.init ();
+ }
+
+ inline void add (hb_codepoint_t g) {
+ head.add (g);
+ tail.add (g);
+ }
+
+ inline bool add_range (hb_codepoint_t a, hb_codepoint_t b) {
+ head.add_range (a, b);
+ tail.add_range (a, b);
+ return true;
+ }
+ template <typename T>
+ inline void add_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
+ {
+ head.add_array (array, count, stride);
+ tail.add_array (array, count, stride);
+ }
+ template <typename T>
+ inline bool add_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
+ {
+ head.add_sorted_array (array, count, stride);
+ tail.add_sorted_array (array, count, stride);
+ return true;
+ }
+
+ inline bool may_have (hb_codepoint_t g) const {
+ return head.may_have (g) && tail.may_have (g);
+ }
+
+ private:
+ 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;
+
+
+#endif /* HB_SET_DIGEST_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-set-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-set-private.hh
index e2010d7626..9c6f3ee37a 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-set-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-set-private.hh
@@ -1,5 +1,5 @@
/*
- * Copyright © 2012 Google, Inc.
+ * Copyright © 2012,2017 Google, Inc.
*
* This is part of HarfBuzz, a text shaping library.
*
@@ -32,254 +32,462 @@
/*
- * 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.
- *
- * Our filters are highly accurate if the lookup covers fairly local
- * set of glyphs, but fully flooded and ineffective if coverage is
- * all over the place.
- *
- * The frozen-set can be used instead of a digest, to trade more
- * memory for 100% accuracy, but in practice, that doesn't look like
- * an attractive trade-off.
+ * hb_set_t
*/
-template <typename mask_t, unsigned int shift>
-struct hb_set_digest_lowest_bits_t
-{
- ASSERT_POD ();
-
- 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;
- }
+/* TODO Keep a free-list so we can free pages that are completely zeroed. At that
+ * point maybe also use a sentinel value for "all-1" pages? */
- inline void add (hb_codepoint_t g) {
- mask |= mask_for (g);
- }
-
- inline void add_range (hb_codepoint_t a, hb_codepoint_t b) {
- if ((b >> shift) - (a >> shift) >= mask_bits - 1)
- mask = (mask_t) -1;
- else {
- mask_t ma = mask_for (a);
- mask_t mb = mask_for (b);
- mask |= mb + (mb - ma) - (mb < ma);
- }
- }
+struct hb_set_t
+{
+ struct page_map_t
+ {
+ inline int cmp (const page_map_t *o) const { return (int) o->major - (int) major; }
- inline bool may_have (hb_codepoint_t g) const {
- return !!(mask & mask_for (g));
- }
+ uint32_t major;
+ uint32_t index;
+ };
- private:
+ struct page_t
+ {
+ inline void init0 (void) { memset (&v, 0, sizeof (v)); }
+ inline void init1 (void) { memset (&v, 0xff, sizeof (v)); }
- static inline mask_t mask_for (hb_codepoint_t g) {
- return ((mask_t) 1) << ((g >> shift) & (mask_bits - 1));
- }
- mask_t mask;
-};
+ inline unsigned int len (void) const
+ { return ARRAY_LENGTH_CONST (v); }
-template <typename head_t, typename tail_t>
-struct hb_set_digest_combiner_t
-{
- ASSERT_POD ();
-
- inline void init (void) {
- head.init ();
- tail.init ();
- }
+ inline bool is_empty (void) const
+ {
+ for (unsigned int i = 0; i < len (); i++)
+ if (v[i])
+ return false;
+ return true;
+ }
- inline void add (hb_codepoint_t g) {
- head.add (g);
- tail.add (g);
- }
+ inline void add (hb_codepoint_t g) { elt (g) |= mask (g); }
+ inline void del (hb_codepoint_t g) { elt (g) &= ~mask (g); }
+ inline bool has (hb_codepoint_t g) const { return !!(elt (g) & mask (g)); }
- inline void add_range (hb_codepoint_t a, hb_codepoint_t b) {
- head.add_range (a, b);
- tail.add_range (a, b);
- }
+ inline void add_range (hb_codepoint_t a, hb_codepoint_t b)
+ {
+ elt_t *la = &elt (a);
+ elt_t *lb = &elt (b);
+ if (la == lb)
+ *la |= (mask (b) << 1) - mask(a);
+ else
+ {
+ *la |= ~(mask (a) - 1);
+ la++;
+
+ memset (la, 0xff, (char *) lb - (char *) la);
+
+ *lb |= ((mask (b) << 1) - 1);
+ }
+ }
- inline bool may_have (hb_codepoint_t g) const {
- return head.may_have (g) && tail.may_have (g);
- }
+ inline bool is_equal (const page_t *other) const
+ {
+ return 0 == memcmp (&v, &other->v, sizeof (v));
+ }
- private:
- head_t head;
- tail_t tail;
-};
+ inline unsigned int get_population (void) const
+ {
+ unsigned int pop = 0;
+ for (unsigned int i = 0; i < len (); i++)
+ pop += _hb_popcount (v[i]);
+ return pop;
+ }
+ inline bool next (hb_codepoint_t *codepoint) const
+ {
+ unsigned int m = (*codepoint + 1) & MASK;
+ if (!m)
+ {
+ *codepoint = INVALID;
+ return false;
+ }
+ unsigned int i = m / ELT_BITS;
+ unsigned int j = m & ELT_MASK;
+
+ for (; j < ELT_BITS; j++)
+ if (v[i] & (elt_t (1) << j))
+ goto found;
+ for (i++; i < len (); i++)
+ if (v[i])
+ for (j = 0; j < ELT_BITS; j++)
+ if (v[i] & (elt_t (1) << j))
+ goto found;
+
+ *codepoint = INVALID;
+ return false;
-/*
- * 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;
+ found:
+ *codepoint = i * ELT_BITS + j;
+ return true;
+ }
+ inline hb_codepoint_t get_min (void) const
+ {
+ for (unsigned int i = 0; i < len (); i++)
+ if (v[i])
+ {
+ elt_t e = v[i];
+ for (unsigned int j = 0; j < ELT_BITS; j++)
+ if (e & (elt_t (1) << j))
+ return i * ELT_BITS + j;
+ }
+ return INVALID;
+ }
+ inline hb_codepoint_t get_max (void) const
+ {
+ for (int i = len () - 1; i >= 0; i--)
+ if (v[i])
+ {
+ elt_t e = v[i];
+ for (int j = ELT_BITS - 1; j >= 0; j--)
+ if (e & (elt_t (1) << j))
+ return i * ELT_BITS + j;
+ }
+ return 0;
+ }
+ static const unsigned int PAGE_BITS = 8192; /* Use to tune. */
+ static_assert ((PAGE_BITS & ((PAGE_BITS) - 1)) == 0, "");
+ typedef uint64_t elt_t;
-/*
- * hb_set_t
- */
+#if 0 && HAVE_VECTOR_SIZE
+ /* The vectorized version does not work with clang as non-const
+ * elt() errs "non-const reference cannot bind to vector element". */
+ typedef elt_t vector_t __attribute__((vector_size (PAGE_BITS / 8)));
+#else
+ typedef hb_vector_size_t<elt_t, PAGE_BITS / 8> vector_t;
+#endif
+ vector_t v;
-/* TODO Make this faster and memmory efficient. */
+ static const unsigned int ELT_BITS = sizeof (elt_t) * 8;
+ static const unsigned int ELT_MASK = ELT_BITS - 1;
+ static const unsigned int BITS = sizeof (vector_t) * 8;
+ static const unsigned int MASK = BITS - 1;
+ static_assert (PAGE_BITS == BITS, "");
-struct hb_set_t
-{
- friend struct hb_frozen_set_t;
+ elt_t &elt (hb_codepoint_t g) { return v[(g & MASK) / ELT_BITS]; }
+ elt_t const &elt (hb_codepoint_t g) const { return v[(g & MASK) / ELT_BITS]; }
+ elt_t mask (hb_codepoint_t g) const { return elt_t (1) << (g & ELT_MASK); }
+ };
+ static_assert (page_t::PAGE_BITS == sizeof (page_t) * 8, "");
hb_object_header_t header;
ASSERT_POD ();
bool in_error;
+ hb_prealloced_array_t<page_map_t, 8> page_map;
+ hb_prealloced_array_t<page_t, 1> pages;
- inline void init (void) {
- hb_object_init (this);
- clear ();
+ inline void init (void)
+ {
+ page_map.init ();
+ pages.init ();
}
- inline void fini (void) {
+ inline void finish (void)
+ {
+ page_map.finish ();
+ pages.finish ();
+ }
+
+ inline bool resize (unsigned int count)
+ {
+ if (unlikely (in_error)) return false;
+ if (!pages.resize (count) || !page_map.resize (count))
+ {
+ pages.resize (page_map.len);
+ in_error = true;
+ return false;
+ }
+ return true;
}
+
inline void clear (void) {
if (unlikely (hb_object_is_inert (this)))
return;
in_error = false;
- memset (elts, 0, sizeof elts);
+ page_map.resize (0);
+ pages.resize (0);
}
inline bool is_empty (void) const {
- for (unsigned int i = 0; i < ARRAY_LENGTH (elts); i++)
- if (elts[i])
+ unsigned int count = pages.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (!pages[i].is_empty ())
return false;
return true;
}
+
inline void add (hb_codepoint_t g)
{
if (unlikely (in_error)) return;
if (unlikely (g == INVALID)) return;
- if (unlikely (g > MAX_G)) return;
- elt (g) |= mask (g);
+ page_t *page = page_for_insert (g); if (unlikely (!page)) return;
+ page->add (g);
}
- inline void add_range (hb_codepoint_t a, hb_codepoint_t b)
+ inline bool add_range (hb_codepoint_t a, hb_codepoint_t b)
+ {
+ if (unlikely (in_error)) return true; /* https://github.com/harfbuzz/harfbuzz/issues/657 */
+ if (unlikely (a > b || a == INVALID || b == INVALID)) return false;
+ unsigned int ma = get_major (a);
+ unsigned int mb = get_major (b);
+ if (ma == mb)
+ {
+ page_t *page = page_for_insert (a); if (unlikely (!page)) return false;
+ page->add_range (a, b);
+ }
+ else
+ {
+ page_t *page = page_for_insert (a); if (unlikely (!page)) return false;
+ page->add_range (a, major_start (ma + 1) - 1);
+
+ for (unsigned int m = ma + 1; m < mb; m++)
+ {
+ page = page_for_insert (major_start (m)); if (unlikely (!page)) return false;
+ page->init1 ();
+ }
+
+ page = page_for_insert (b); if (unlikely (!page)) return false;
+ page->add_range (major_start (mb), b);
+ }
+ return true;
+ }
+
+ template <typename T>
+ inline void add_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
{
if (unlikely (in_error)) return;
- /* TODO Speedup */
- for (unsigned int i = a; i < b + 1; i++)
- add (i);
+ if (!count) return;
+ hb_codepoint_t g = *array;
+ while (count)
+ {
+ unsigned int m = get_major (g);
+ page_t *page = page_for_insert (g); if (unlikely (!page)) return;
+ unsigned int start = major_start (m);
+ unsigned int end = major_start (m + 1);
+ do
+ {
+ page->add (g);
+
+ array++;
+ count--;
+ }
+ while (count && (g = *array, start <= g && g < end));
+ }
+ }
+
+ /* Might return false if array looks unsorted.
+ * Used for faster rejection of corrupt data. */
+ template <typename T>
+ inline bool add_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
+ {
+ if (unlikely (in_error)) return true; /* https://github.com/harfbuzz/harfbuzz/issues/657 */
+ if (!count) return true;
+ hb_codepoint_t g = *array;
+ hb_codepoint_t last_g = g;
+ while (count)
+ {
+ unsigned int m = get_major (g);
+ page_t *page = page_for_insert (g); if (unlikely (!page)) return false;
+ unsigned int end = major_start (m + 1);
+ do
+ {
+ /* If we try harder we can change the following comparison to <=;
+ * Not sure if it's worth it. */
+ if (g < last_g) return false;
+ last_g = g;
+ page->add (g);
+
+ array++;
+ count--;
+ }
+ while (count && (g = *array, g < end));
+ }
+ return true;
}
+
inline void del (hb_codepoint_t g)
{
if (unlikely (in_error)) return;
- if (unlikely (g > MAX_G)) return;
- elt (g) &= ~mask (g);
+ page_t *p = page_for (g);
+ if (!p)
+ return;
+ p->del (g);
}
inline void del_range (hb_codepoint_t a, hb_codepoint_t b)
{
+ /* TODO Optimize, like add_range(). */
if (unlikely (in_error)) return;
- /* TODO Speedup */
for (unsigned int i = a; i < b + 1; i++)
del (i);
}
inline bool has (hb_codepoint_t g) const
{
- if (unlikely (g > MAX_G)) return false;
- return !!(elt (g) & mask (g));
+ const page_t *p = page_for (g);
+ if (!p)
+ return false;
+ return p->has (g);
}
inline bool intersects (hb_codepoint_t first,
hb_codepoint_t last) const
{
- if (unlikely (first > MAX_G)) return false;
- if (unlikely (last > MAX_G)) last = MAX_G;
- unsigned int end = last + 1;
- for (hb_codepoint_t i = first; i < end; i++)
- if (has (i))
- return true;
- return false;
+ hb_codepoint_t c = first - 1;
+ return next (&c) && c <= last;
+ }
+ inline void set (const hb_set_t *other)
+ {
+ if (unlikely (in_error)) return;
+ unsigned int count = other->pages.len;
+ if (!resize (count))
+ return;
+
+ memcpy (pages.array, other->pages.array, count * sizeof (pages.array[0]));
+ memcpy (page_map.array, other->page_map.array, count * sizeof (page_map.array[0]));
}
+
inline bool is_equal (const hb_set_t *other) const
{
- for (unsigned int i = 0; i < ELTS; i++)
- if (elts[i] != other->elts[i])
+ unsigned int na = pages.len;
+ unsigned int nb = other->pages.len;
+
+ unsigned int a = 0, b = 0;
+ for (; a < na && b < nb; )
+ {
+ if (page_at (a).is_empty ()) { a++; continue; }
+ if (other->page_at (b).is_empty ()) { b++; continue; }
+ if (page_map[a].major != other->page_map[b].major ||
+ !page_at (a).is_equal (&other->page_at (b)))
return false;
+ a++;
+ b++;
+ }
+ for (; a < na; a++)
+ if (!page_at (a).is_empty ()) { return false; }
+ for (; b < nb; b++)
+ if (!other->page_at (b).is_empty ()) { return false; }
+
return true;
}
- inline void set (const hb_set_t *other)
+
+ template <class Op>
+ inline void process (const hb_set_t *other)
{
if (unlikely (in_error)) return;
- for (unsigned int i = 0; i < ELTS; i++)
- elts[i] = other->elts[i];
+
+ unsigned int na = pages.len;
+ unsigned int nb = other->pages.len;
+
+ unsigned int count = 0;
+ unsigned int a = 0, b = 0;
+ for (; a < na && b < nb; )
+ {
+ if (page_map[a].major == other->page_map[b].major)
+ {
+ count++;
+ a++;
+ b++;
+ }
+ else if (page_map[a].major < other->page_map[b].major)
+ {
+ if (Op::passthru_left)
+ count++;
+ a++;
+ }
+ else
+ {
+ if (Op::passthru_right)
+ count++;
+ b++;
+ }
+ }
+ if (Op::passthru_left)
+ count += na - a;
+ if (Op::passthru_right)
+ count += nb - b;
+
+ if (!resize (count))
+ return;
+
+ /* Process in-place backward. */
+ a = na;
+ b = nb;
+ for (; a && b; )
+ {
+ if (page_map[a - 1].major == other->page_map[b - 1].major)
+ {
+ a--;
+ b--;
+ Op::process (page_at (--count).v, page_at (a).v, other->page_at (b).v);
+ }
+ else if (page_map[a - 1].major > other->page_map[b - 1].major)
+ {
+ a--;
+ if (Op::passthru_left)
+ page_at (--count).v = page_at (a).v;
+ }
+ else
+ {
+ b--;
+ if (Op::passthru_right)
+ page_at (--count).v = other->page_at (b).v;
+ }
+ }
+ if (Op::passthru_left)
+ while (a)
+ page_at (--count).v = page_at (--a).v;
+ if (Op::passthru_right)
+ while (b)
+ page_at (--count).v = other->page_at (--b).v;
+ assert (!count);
}
+
inline void union_ (const hb_set_t *other)
{
- if (unlikely (in_error)) return;
- for (unsigned int i = 0; i < ELTS; i++)
- elts[i] |= other->elts[i];
+ process<HbOpOr> (other);
}
inline void intersect (const hb_set_t *other)
{
- if (unlikely (in_error)) return;
- for (unsigned int i = 0; i < ELTS; i++)
- elts[i] &= other->elts[i];
+ process<HbOpAnd> (other);
}
inline void subtract (const hb_set_t *other)
{
- if (unlikely (in_error)) return;
- for (unsigned int i = 0; i < ELTS; i++)
- elts[i] &= ~other->elts[i];
+ process<HbOpMinus> (other);
}
inline void symmetric_difference (const hb_set_t *other)
{
- if (unlikely (in_error)) return;
- for (unsigned int i = 0; i < ELTS; i++)
- elts[i] ^= other->elts[i];
- }
- inline void invert (void)
- {
- if (unlikely (in_error)) return;
- for (unsigned int i = 0; i < ELTS; i++)
- elts[i] = ~elts[i];
+ process<HbOpXor> (other);
}
inline bool next (hb_codepoint_t *codepoint) const
{
if (unlikely (*codepoint == INVALID)) {
- hb_codepoint_t i = get_min ();
- if (i != INVALID) {
- *codepoint = i;
- return true;
- } else {
- *codepoint = INVALID;
- return false;
+ *codepoint = get_min ();
+ return *codepoint != INVALID;
+ }
+
+ page_map_t map = {get_major (*codepoint), 0};
+ unsigned int i;
+ page_map.bfind (&map, &i);
+ if (i < page_map.len)
+ {
+ if (pages[page_map[i].index].next (codepoint))
+ {
+ *codepoint += page_map[i].major * page_t::PAGE_BITS;
+ return true;
}
+ i++;
}
- for (hb_codepoint_t i = *codepoint + 1; i < MAX_G + 1; i++)
- if (has (i)) {
- *codepoint = i;
+ for (; i < page_map.len; i++)
+ {
+ hb_codepoint_t m = pages[page_map[i].index].get_min ();
+ if (m != INVALID)
+ {
+ *codepoint = page_map[i].major * page_t::PAGE_BITS + m;
return true;
}
+ }
*codepoint = INVALID;
return false;
}
@@ -303,99 +511,66 @@ struct hb_set_t
inline unsigned int get_population (void) const
{
- unsigned int count = 0;
- for (unsigned int i = 0; i < ELTS; i++)
- count += _hb_popcount32 (elts[i]);
- return count;
+ unsigned int pop = 0;
+ unsigned int count = pages.len;
+ for (unsigned int i = 0; i < count; i++)
+ pop += pages[i].get_population ();
+ return pop;
}
inline hb_codepoint_t get_min (void) const
{
- for (unsigned int i = 0; i < ELTS; i++)
- if (elts[i])
- for (unsigned int j = 0; j < BITS; j++)
- if (elts[i] & (1u << j))
- return i * BITS + j;
+ unsigned int count = pages.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (!page_at (i).is_empty ())
+ return page_map[i].major * page_t::PAGE_BITS + page_at (i).get_min ();
return INVALID;
}
inline hb_codepoint_t get_max (void) const
{
- for (unsigned int i = ELTS; i; i--)
- if (elts[i - 1])
- for (unsigned int j = BITS; j; j--)
- if (elts[i - 1] & (1u << (j - 1)))
- return (i - 1) * BITS + (j - 1);
+ unsigned int count = pages.len;
+ for (int i = count - 1; i >= 0; i++)
+ if (!page_at (i).is_empty ())
+ return page_map[i].major * page_t::PAGE_BITS + page_at (i).get_max ();
return INVALID;
}
- typedef uint32_t elt_t;
- static const unsigned int MAX_G = 65536 - 1; /* XXX Fix this... */
- static const unsigned int SHIFT = 5;
- static const unsigned int BITS = (1 << SHIFT);
- static const unsigned int MASK = BITS - 1;
- static const unsigned int ELTS = (MAX_G + 1 + (BITS - 1)) / BITS;
static const hb_codepoint_t INVALID = HB_SET_VALUE_INVALID;
- elt_t &elt (hb_codepoint_t g) { return elts[g >> SHIFT]; }
- elt_t const &elt (hb_codepoint_t g) const { return elts[g >> SHIFT]; }
- elt_t mask (hb_codepoint_t g) const { return elt_t (1) << (g & MASK); }
-
- elt_t elts[ELTS]; /* XXX 8kb */
-
- ASSERT_STATIC (sizeof (elt_t) * 8 == BITS);
- ASSERT_STATIC (sizeof (elt_t) * 8 * ELTS > MAX_G);
-};
-
-struct hb_frozen_set_t
-{
- static const unsigned int SHIFT = hb_set_t::SHIFT;
- static const unsigned int BITS = hb_set_t::BITS;
- static const unsigned int MASK = hb_set_t::MASK;
- typedef hb_set_t::elt_t elt_t;
-
- inline void init (const hb_set_t &set)
+ inline page_t *page_for_insert (hb_codepoint_t g)
{
- start = count = 0;
- elts = NULL;
-
- unsigned int max = set.get_max ();
- if (max == set.INVALID)
- return;
- unsigned int min = set.get_min ();
- const elt_t &min_elt = set.elt (min);
-
- start = min & ~MASK;
- count = max - start + 1;
- unsigned int num_elts = (count + BITS - 1) / BITS;
- unsigned int elts_size = num_elts * sizeof (elt_t);
- elts = (elt_t *) malloc (elts_size);
- if (unlikely (!elts))
+ page_map_t map = {get_major (g), pages.len};
+ unsigned int i;
+ if (!page_map.bfind (&map, &i))
{
- start = count = 0;
- return;
+ if (!resize (pages.len + 1))
+ return nullptr;
+
+ pages[map.index].init0 ();
+ memmove (&page_map[i + 1], &page_map[i], (page_map.len - 1 - i) * sizeof (page_map[0]));
+ page_map[i] = map;
}
- memcpy (elts, &min_elt, elts_size);
+ return &pages[page_map[i].index];
}
-
- inline void fini (void)
+ inline page_t *page_for (hb_codepoint_t g)
{
- if (elts)
- free (elts);
+ page_map_t key = {get_major (g)};
+ const page_map_t *found = page_map.bsearch (&key);
+ if (found)
+ return &pages[found->index];
+ return nullptr;
}
-
- inline bool has (hb_codepoint_t g) const
+ inline const page_t *page_for (hb_codepoint_t g) const
{
- /* hb_codepoint_t is unsigned. */
- g -= start;
- if (unlikely (g > count)) return false;
- return !!(elt (g) & mask (g));
- }
-
- elt_t const &elt (hb_codepoint_t g) const { return elts[g >> SHIFT]; }
- elt_t mask (hb_codepoint_t g) const { return elt_t (1) << (g & MASK); }
-
- private:
- hb_codepoint_t start, count;
- elt_t *elts;
+ page_map_t key = {get_major (g)};
+ const page_map_t *found = page_map.bsearch (&key);
+ if (found)
+ return &pages[found->index];
+ return nullptr;
+ }
+ inline page_t &page_at (unsigned int i) { return pages[page_map[i].index]; }
+ inline const page_t &page_at (unsigned int i) const { return pages[page_map[i].index]; }
+ inline unsigned int get_major (hb_codepoint_t g) const { return g / page_t::PAGE_BITS; }
+ inline hb_codepoint_t major_start (unsigned int major) const { return major * page_t::PAGE_BITS; }
};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-set.cc b/src/3rdparty/harfbuzz-ng/src/hb-set.cc
index cb7fcdbf64..0b4f871e85 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-set.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-set.cc
@@ -45,7 +45,7 @@ hb_set_create (void)
if (!(set = hb_object_create<hb_set_t> ()))
return hb_set_get_empty ();
- set->clear ();
+ set->init ();
return set;
}
@@ -95,7 +95,7 @@ hb_set_destroy (hb_set_t *set)
{
if (!hb_object_destroy (set)) return;
- set->fini ();
+ set->finish ();
free (set);
}
@@ -105,7 +105,7 @@ hb_set_destroy (hb_set_t *set)
* @set: a set.
* @key:
* @data:
- * @destroy (closure data):
+ * @destroy:
* @replace:
*
* Return value:
@@ -376,11 +376,12 @@ hb_set_symmetric_difference (hb_set_t *set,
*
*
* Since: 0.9.10
+ *
+ * Deprecated: 1.6.1
**/
void
hb_set_invert (hb_set_t *set)
{
- set->invert ();
}
/**
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-set.h b/src/3rdparty/harfbuzz-ng/src/hb-set.h
index 2164c1a654..2ce406073c 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-set.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-set.h
@@ -126,9 +126,6 @@ HB_EXTERN void
hb_set_symmetric_difference (hb_set_t *set,
const hb_set_t *other);
-HB_EXTERN void
-hb_set_invert (hb_set_t *set);
-
HB_EXTERN unsigned int
hb_set_get_population (const hb_set_t *set);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc
index 600faaeb18..6eeba2b3d1 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc
@@ -24,24 +24,14 @@
* Google Author(s): Behdad Esfahbod
*/
+#include "hb-private.hh"
+#include "hb-debug.hh"
#include "hb-shape-plan-private.hh"
#include "hb-shaper-private.hh"
#include "hb-font-private.hh"
#include "hb-buffer-private.hh"
-#ifndef HB_DEBUG_SHAPE_PLAN
-#define HB_DEBUG_SHAPE_PLAN (HB_DEBUG+0)
-#endif
-
-
-#define HB_SHAPER_IMPLEMENT(shaper) \
- HB_SHAPER_DATA_ENSURE_DECLARE(shaper, face) \
- HB_SHAPER_DATA_ENSURE_DECLARE(shaper, font)
-#include "hb-shaper-list.hh"
-#undef HB_SHAPER_IMPLEMENT
-
-
static void
hb_shape_plan_plan (hb_shape_plan_t *shape_plan,
const hb_feature_t *user_features,
@@ -122,7 +112,7 @@ hb_shape_plan_create (hb_face_t *face,
{
return hb_shape_plan_create2 (face, props,
user_features, num_user_features,
- NULL, 0,
+ nullptr, 0,
shaper_list);
}
@@ -135,7 +125,7 @@ hb_shape_plan_create2 (hb_face_t *face,
unsigned int num_coords,
const char * const *shaper_list)
{
- DEBUG_MSG_FUNC (SHAPE_PLAN, NULL,
+ DEBUG_MSG_FUNC (SHAPE_PLAN, nullptr,
"face=%p num_features=%d num_coords=%d shaper_list=%p",
face,
num_user_features,
@@ -143,8 +133,8 @@ hb_shape_plan_create2 (hb_face_t *face,
shaper_list);
hb_shape_plan_t *shape_plan;
- hb_feature_t *features = NULL;
- int *coords = NULL;
+ hb_feature_t *features = nullptr;
+ int *coords = nullptr;
if (unlikely (!face))
face = hb_face_get_empty ();
@@ -167,7 +157,7 @@ hb_shape_plan_create2 (hb_face_t *face,
assert (props->direction != HB_DIRECTION_INVALID);
hb_face_make_immutable (face);
- shape_plan->default_shaper_list = shaper_list == NULL;
+ shape_plan->default_shaper_list = !shaper_list;
shape_plan->face_unsafe = face;
shape_plan->props = *props;
shape_plan->num_user_features = num_user_features;
@@ -203,16 +193,16 @@ hb_shape_plan_get_empty (void)
HB_OBJECT_HEADER_STATIC,
true, /* default_shaper_list */
- NULL, /* face */
+ nullptr, /* face */
HB_SEGMENT_PROPERTIES_DEFAULT, /* props */
- NULL, /* shaper_func */
- NULL, /* shaper_name */
+ nullptr, /* shaper_func */
+ nullptr, /* shaper_name */
- NULL, /* user_features */
+ nullptr, /* user_features */
0, /* num_user_featurs */
- NULL, /* coords */
+ nullptr, /* coords */
0, /* num_coords */
{
@@ -430,7 +420,7 @@ hb_shape_plan_matches (const hb_shape_plan_t *shape_plan,
return hb_segment_properties_equal (&shape_plan->props, &proposal->props) &&
hb_shape_plan_user_features_match (shape_plan, proposal) &&
hb_shape_plan_coords_match (shape_plan, proposal) &&
- ((shape_plan->default_shaper_list && proposal->shaper_list == NULL) ||
+ ((shape_plan->default_shaper_list && !proposal->shaper_list) ||
(shape_plan->shaper_func == proposal->shaper_func));
}
@@ -438,11 +428,12 @@ static inline hb_bool_t
hb_non_global_user_features_present (const hb_feature_t *user_features,
unsigned int num_user_features)
{
- while (num_user_features)
+ while (num_user_features) {
if (user_features->start != 0 || user_features->end != (unsigned int) -1)
return true;
- else
- num_user_features--, user_features++;
+ num_user_features--;
+ user_features++;
+ }
return false;
}
@@ -476,7 +467,7 @@ hb_shape_plan_create_cached (hb_face_t *face,
{
return hb_shape_plan_create_cached2 (face, props,
user_features, num_user_features,
- NULL, 0,
+ nullptr, 0,
shaper_list);
}
@@ -489,7 +480,7 @@ hb_shape_plan_create_cached2 (hb_face_t *face,
unsigned int num_coords,
const char * const *shaper_list)
{
- DEBUG_MSG_FUNC (SHAPE_PLAN, NULL,
+ DEBUG_MSG_FUNC (SHAPE_PLAN, nullptr,
"face=%p num_features=%d shaper_list=%p",
face,
num_user_features,
@@ -500,7 +491,7 @@ hb_shape_plan_create_cached2 (hb_face_t *face,
shaper_list,
user_features,
num_user_features,
- NULL
+ nullptr
};
if (shaper_list) {
@@ -526,15 +517,17 @@ hb_shape_plan_create_cached2 (hb_face_t *face,
retry:
hb_face_t::plan_node_t *cached_plan_nodes = (hb_face_t::plan_node_t *) hb_atomic_ptr_get (&face->shape_plans);
- for (hb_face_t::plan_node_t *node = cached_plan_nodes; node; node = node->next)
- if (hb_shape_plan_matches (node->shape_plan, &proposal))
- {
- DEBUG_MSG_FUNC (SHAPE_PLAN, node->shape_plan, "fulfilled from cache");
- return hb_shape_plan_reference (node->shape_plan);
- }
- /* Not found. */
+ /* Don't look for plan in the cache if there were variation coordinates XXX Fix me. */
+ if (!hb_coords_present (coords, num_coords))
+ for (hb_face_t::plan_node_t *node = cached_plan_nodes; node; node = node->next)
+ if (hb_shape_plan_matches (node->shape_plan, &proposal))
+ {
+ DEBUG_MSG_FUNC (SHAPE_PLAN, node->shape_plan, "fulfilled from cache");
+ return hb_shape_plan_reference (node->shape_plan);
+ }
+ /* Not found. */
hb_shape_plan_t *shape_plan = hb_shape_plan_create2 (face, props,
user_features, num_user_features,
coords, num_coords,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-shape.cc
index 706f14420d..39355b337d 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-shape.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shape.cc
@@ -45,254 +45,6 @@
* contains the output glyphs and their positions.
**/
-static bool
-parse_space (const char **pp, const char *end)
-{
- while (*pp < end && ISSPACE (**pp))
- (*pp)++;
- return true;
-}
-
-static bool
-parse_char (const char **pp, const char *end, char c)
-{
- parse_space (pp, end);
-
- if (*pp == end || **pp != c)
- return false;
-
- (*pp)++;
- return true;
-}
-
-static bool
-parse_uint (const char **pp, const char *end, unsigned int *pv)
-{
- char buf[32];
- unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp));
- strncpy (buf, *pp, len);
- buf[len] = '\0';
-
- char *p = buf;
- char *pend = p;
- unsigned int v;
-
- /* Intentionally use strtol instead of strtoul, such that
- * -1 turns into "big number"... */
- errno = 0;
- v = strtol (p, &pend, 0);
- if (errno || p == pend)
- return false;
-
- *pv = v;
- *pp += pend - p;
- return true;
-}
-
-static bool
-parse_bool (const char **pp, const char *end, unsigned int *pv)
-{
- parse_space (pp, end);
-
- const char *p = *pp;
- while (*pp < end && ISALPHA(**pp))
- (*pp)++;
-
- /* CSS allows on/off as aliases 1/0. */
- if (*pp - p == 2 || 0 == strncmp (p, "on", 2))
- *pv = 1;
- else if (*pp - p == 3 || 0 == strncmp (p, "off", 2))
- *pv = 0;
- else
- return false;
-
- return true;
-}
-
-static bool
-parse_feature_value_prefix (const char **pp, const char *end, hb_feature_t *feature)
-{
- if (parse_char (pp, end, '-'))
- feature->value = 0;
- else {
- parse_char (pp, end, '+');
- feature->value = 1;
- }
-
- return true;
-}
-
-static bool
-parse_feature_tag (const char **pp, const char *end, hb_feature_t *feature)
-{
- parse_space (pp, end);
-
- char quote = 0;
-
- if (*pp < end && (**pp == '\'' || **pp == '"'))
- {
- quote = **pp;
- (*pp)++;
- }
-
- const char *p = *pp;
- while (*pp < end && ISALNUM(**pp))
- (*pp)++;
-
- if (p == *pp || *pp - p > 4)
- return false;
-
- feature->tag = hb_tag_from_string (p, *pp - p);
-
- if (quote)
- {
- /* CSS expects exactly four bytes. And we only allow quotations for
- * CSS compatibility. So, enforce the length. */
- if (*pp - p != 4)
- return false;
- if (*pp == end || **pp != quote)
- return false;
- (*pp)++;
- }
-
- return true;
-}
-
-static bool
-parse_feature_indices (const char **pp, const char *end, hb_feature_t *feature)
-{
- parse_space (pp, end);
-
- bool has_start;
-
- feature->start = 0;
- feature->end = (unsigned int) -1;
-
- if (!parse_char (pp, end, '['))
- return true;
-
- has_start = parse_uint (pp, end, &feature->start);
-
- if (parse_char (pp, end, ':')) {
- parse_uint (pp, end, &feature->end);
- } else {
- if (has_start)
- feature->end = feature->start + 1;
- }
-
- return parse_char (pp, end, ']');
-}
-
-static bool
-parse_feature_value_postfix (const char **pp, const char *end, hb_feature_t *feature)
-{
- bool had_equal = parse_char (pp, end, '=');
- bool had_value = parse_uint (pp, end, &feature->value) ||
- parse_bool (pp, end, &feature->value);
- /* CSS doesn't use equal-sign between tag and value.
- * If there was an equal-sign, then there *must* be a value.
- * A value without an eqaul-sign is ok, but not required. */
- return !had_equal || had_value;
-}
-
-
-static bool
-parse_one_feature (const char **pp, const char *end, hb_feature_t *feature)
-{
- return parse_feature_value_prefix (pp, end, feature) &&
- parse_feature_tag (pp, end, feature) &&
- parse_feature_indices (pp, end, feature) &&
- parse_feature_value_postfix (pp, end, feature) &&
- parse_space (pp, end) &&
- *pp == end;
-}
-
-/**
- * hb_feature_from_string:
- * @str: (array length=len) (element-type uint8_t): a string to parse
- * @len: length of @str, or -1 if string is %NULL terminated
- * @feature: (out): the #hb_feature_t to initialize with the parsed values
- *
- * Parses a string into a #hb_feature_t.
- *
- * TODO: document the syntax here.
- *
- * Return value:
- * %true if @str is successfully parsed, %false otherwise.
- *
- * Since: 0.9.5
- **/
-hb_bool_t
-hb_feature_from_string (const char *str, int len,
- hb_feature_t *feature)
-{
- hb_feature_t feat;
-
- if (len < 0)
- len = strlen (str);
-
- if (likely (parse_one_feature (&str, str + len, &feat)))
- {
- if (feature)
- *feature = feat;
- return true;
- }
-
- if (feature)
- memset (feature, 0, sizeof (*feature));
- return false;
-}
-
-/**
- * hb_feature_to_string:
- * @feature: an #hb_feature_t to convert
- * @buf: (array length=size) (out): output string
- * @size: the allocated size of @buf
- *
- * Converts a #hb_feature_t into a %NULL-terminated string in the format
- * understood by hb_feature_from_string(). The client in responsible for
- * allocating big enough size for @buf, 128 bytes is more than enough.
- *
- * Since: 0.9.5
- **/
-void
-hb_feature_to_string (hb_feature_t *feature,
- char *buf, unsigned int size)
-{
- if (unlikely (!size)) return;
-
- char s[128];
- unsigned int len = 0;
- if (feature->value == 0)
- s[len++] = '-';
- hb_tag_to_string (feature->tag, s + len);
- len += 4;
- while (len && s[len - 1] == ' ')
- len--;
- if (feature->start != 0 || feature->end != (unsigned int) -1)
- {
- s[len++] = '[';
- if (feature->start)
- len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->start));
- if (feature->end != feature->start + 1) {
- s[len++] = ':';
- if (feature->end != (unsigned int) -1)
- len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->end));
- }
- s[len++] = ']';
- }
- if (feature->value > 1)
- {
- s[len++] = '=';
- len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->value));
- }
- assert (len < ARRAY_LENGTH (s));
- len = MIN (len, size - 1);
- memcpy (buf, s, len);
- buf[len] = '\0';
-}
-
-
static const char **static_shaper_list;
#ifdef HB_USE_ATEXIT
@@ -324,7 +76,7 @@ retry:
/* Not found; allocate one. */
shaper_list = (const char **) calloc (1 + HB_SHAPERS_COUNT, sizeof (const char *));
if (unlikely (!shaper_list)) {
- static const char *nil_shaper_list[] = {NULL};
+ static const char *nil_shaper_list[] = {nullptr};
return nil_shaper_list;
}
@@ -332,9 +84,9 @@ retry:
unsigned int i;
for (i = 0; i < HB_SHAPERS_COUNT; i++)
shaper_list[i] = shapers[i].name;
- shaper_list[i] = NULL;
+ shaper_list[i] = nullptr;
- if (!hb_atomic_ptr_cmpexch (&static_shaper_list, NULL, shaper_list)) {
+ if (!hb_atomic_ptr_cmpexch (&static_shaper_list, nullptr, shaper_list)) {
free (shaper_list);
goto retry;
}
@@ -362,7 +114,7 @@ retry:
* shapers will be used in the given order, otherwise the default shapers list
* will be used.
*
- * Return value: %FALSE if all shapers failed, %TRUE otherwise
+ * Return value: false if all shapers failed, true otherwise
*
* Since: 0.9.2
**/
@@ -405,5 +157,5 @@ hb_shape (hb_font_t *font,
const hb_feature_t *features,
unsigned int num_features)
{
- hb_shape_full (font, buffer, features, num_features, NULL);
+ hb_shape_full (font, buffer, features, num_features, nullptr);
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape.h b/src/3rdparty/harfbuzz-ng/src/hb-shape.h
index 53bb845bf4..39507ff744 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-shape.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shape.h
@@ -40,22 +40,6 @@
HB_BEGIN_DECLS
-typedef struct hb_feature_t {
- hb_tag_t tag;
- uint32_t value;
- unsigned int start;
- unsigned int end;
-} hb_feature_t;
-
-HB_EXTERN hb_bool_t
-hb_feature_from_string (const char *str, int len,
- hb_feature_t *feature);
-
-HB_EXTERN void
-hb_feature_to_string (hb_feature_t *feature,
- char *buf, unsigned int size);
-
-
HB_EXTERN void
hb_shape (hb_font_t *font,
hb_buffer_t *buffer,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shaper-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-shaper-private.hh
index d1d1146dad..ce2d9f2839 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-shaper-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shaper-private.hh
@@ -65,35 +65,51 @@ struct hb_shaper_data_t {
#define HB_SHAPER_DATA_INVALID ((void *) -1)
#define HB_SHAPER_DATA_IS_INVALID(data) ((void *) (data) == HB_SHAPER_DATA_INVALID)
-#define HB_SHAPER_DATA_TYPE(shaper, object) struct hb_##shaper##_shaper_##object##_data_t
+#define HB_SHAPER_DATA_TYPE_NAME(shaper, object) hb_##shaper##_shaper_##object##_data_t
+#define HB_SHAPER_DATA_TYPE(shaper, object) struct HB_SHAPER_DATA_TYPE_NAME(shaper, object)
#define HB_SHAPER_DATA_INSTANCE(shaper, object, instance) (* (HB_SHAPER_DATA_TYPE(shaper, object) **) &(instance)->shaper_data.shaper)
-#define HB_SHAPER_DATA(shaper, object) HB_SHAPER_DATA_INSTANCE (shaper, object, object)
+#define HB_SHAPER_DATA(shaper, object) HB_SHAPER_DATA_INSTANCE(shaper, object, object)
#define HB_SHAPER_DATA_CREATE_FUNC(shaper, object) _hb_##shaper##_shaper_##object##_data_create
#define HB_SHAPER_DATA_DESTROY_FUNC(shaper, object) _hb_##shaper##_shaper_##object##_data_destroy
+#define HB_SHAPER_DATA_ENSURE_FUNC(shaper, object) hb_##shaper##_shaper_##object##_data_ensure
#define HB_SHAPER_DATA_PROTOTYPE(shaper, object) \
HB_SHAPER_DATA_TYPE (shaper, object); /* Type forward declaration. */ \
extern "C" HB_INTERNAL HB_SHAPER_DATA_TYPE (shaper, object) * \
HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (hb_##object##_t *object HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS); \
extern "C" HB_INTERNAL void \
- HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (HB_SHAPER_DATA_TYPE (shaper, object) *data)
+ HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (HB_SHAPER_DATA_TYPE (shaper, object) *data); \
+ extern "C" HB_INTERNAL bool \
+ HB_SHAPER_DATA_ENSURE_FUNC (shaper, object) (hb_##object##_t *object)
#define HB_SHAPER_DATA_DESTROY(shaper, object) \
if (HB_SHAPER_DATA_TYPE (shaper, object) *data = HB_SHAPER_DATA (shaper, object)) \
if (data != HB_SHAPER_DATA_INVALID && data != HB_SHAPER_DATA_SUCCEEDED) \
HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data);
-#define HB_SHAPER_DATA_ENSURE_DECLARE(shaper, object) \
-static inline bool \
-hb_##shaper##_shaper_##object##_data_ensure (hb_##object##_t *object) \
+#define HB_SHAPER_DATA_ENSURE_DEFINE(shaper, object) \
+ HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(shaper, object, true)
+
+#define HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(shaper, object, condition) \
+bool \
+HB_SHAPER_DATA_ENSURE_FUNC(shaper, object) (hb_##object##_t *object) \
{\
retry: \
HB_SHAPER_DATA_TYPE (shaper, object) *data = (HB_SHAPER_DATA_TYPE (shaper, object) *) hb_atomic_ptr_get (&HB_SHAPER_DATA (shaper, object)); \
+ if (likely (data) && !(condition)) { \
+ /* Drop and recreate. */ \
+ /* If someone dropped it in the mean time, throw it away and don't touch it. \
+ * Otherwise, destruct it. */ \
+ if (hb_atomic_ptr_cmpexch (&HB_SHAPER_DATA (shaper, object), data, nullptr)) { \
+ HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data); \
+ } \
+ goto retry; \
+ } \
if (unlikely (!data)) { \
data = HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (object); \
if (unlikely (!data)) \
data = (HB_SHAPER_DATA_TYPE (shaper, object) *) HB_SHAPER_DATA_INVALID; \
- if (!hb_atomic_ptr_cmpexch (&HB_SHAPER_DATA (shaper, object), NULL, data)) { \
+ if (!hb_atomic_ptr_cmpexch (&HB_SHAPER_DATA (shaper, object), nullptr, data)) { \
if (data && \
data != HB_SHAPER_DATA_INVALID && \
data != HB_SHAPER_DATA_SUCCEEDED) \
@@ -101,7 +117,7 @@ hb_##shaper##_shaper_##object##_data_ensure (hb_##object##_t *object) \
goto retry; \
} \
} \
- return data != NULL && !HB_SHAPER_DATA_IS_INVALID (data); \
+ return data != nullptr && !HB_SHAPER_DATA_IS_INVALID (data); \
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shaper.cc b/src/3rdparty/harfbuzz-ng/src/hb-shaper.cc
index b25566d8a7..2c44cf2653 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-shaper.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shaper.cc
@@ -59,14 +59,14 @@ retry:
{
char *env = getenv ("HB_SHAPER_LIST");
if (!env || !*env) {
- (void) hb_atomic_ptr_cmpexch (&static_shapers, NULL, &all_shapers[0]);
+ (void) hb_atomic_ptr_cmpexch (&static_shapers, nullptr, &all_shapers[0]);
return (const hb_shaper_pair_t *) all_shapers;
}
/* Not found; allocate one. */
shapers = (hb_shaper_pair_t *) calloc (1, sizeof (all_shapers));
if (unlikely (!shapers)) {
- (void) hb_atomic_ptr_cmpexch (&static_shapers, NULL, &all_shapers[0]);
+ (void) hb_atomic_ptr_cmpexch (&static_shapers, nullptr, &all_shapers[0]);
return (const hb_shaper_pair_t *) all_shapers;
}
@@ -97,7 +97,7 @@ retry:
p = end + 1;
}
- if (!hb_atomic_ptr_cmpexch (&static_shapers, NULL, shapers)) {
+ if (!hb_atomic_ptr_cmpexch (&static_shapers, nullptr, shapers)) {
free (shapers);
goto retry;
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-string-array.hh b/src/3rdparty/harfbuzz-ng/src/hb-string-array.hh
new file mode 100644
index 0000000000..ba829b0cf0
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-string-array.hh
@@ -0,0 +1,81 @@
+/*
+ * 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_STRING_ARRAY_HH
+#if 0 /* Make checks happy. */
+#define HB_STRING_ARRAY_HH
+#endif
+
+#include "hb-private.hh"
+
+/* Based on Bruno Haible's code in Appendix B of Ulrich Drepper's dsohowto.pdf:
+ * https://software.intel.com/sites/default/files/m/a/1/e/dsohowto.pdf */
+
+#define HB_STRING_ARRAY_TYPE_NAME HB_PASTE(HB_STRING_ARRAY_NAME, _msgstr_t)
+#define HB_STRING_ARRAY_POOL_NAME HB_PASTE(HB_STRING_ARRAY_NAME, _msgstr)
+#define HB_STRING_ARRAY_OFFS_NAME HB_PASTE(HB_STRING_ARRAY_NAME, _msgidx)
+
+static const union HB_STRING_ARRAY_TYPE_NAME {
+ struct {
+/* I like to avoid storing the nul-termination byte since we don't need it,
+ * but C++ does not allow that.
+ * https://stackoverflow.com/questions/28433862/why-initializer-string-for-array-of-chars-is-too-long-compiles-fine-in-c-not
+ */
+#define _S(s) char HB_PASTE (str, __LINE__)[sizeof (s)];
+#include HB_STRING_ARRAY_LIST
+#undef _S
+ } st;
+ char str[VAR];
+}
+HB_STRING_ARRAY_POOL_NAME =
+{
+ {
+#define _S(s) s,
+#include HB_STRING_ARRAY_LIST
+#undef _S
+ }
+};
+static const unsigned int HB_STRING_ARRAY_OFFS_NAME[] =
+{
+#define _S(s) offsetof (union HB_STRING_ARRAY_TYPE_NAME, st.HB_PASTE(str, __LINE__)),
+#include HB_STRING_ARRAY_LIST
+#undef _S
+ sizeof (HB_STRING_ARRAY_TYPE_NAME)
+};
+
+static inline hb_string_t
+HB_STRING_ARRAY_NAME (unsigned int i)
+{
+ assert (i < ARRAY_LENGTH (HB_STRING_ARRAY_OFFS_NAME) - 1);
+ return hb_string_t (HB_STRING_ARRAY_POOL_NAME.str + HB_STRING_ARRAY_OFFS_NAME[i],
+ HB_STRING_ARRAY_OFFS_NAME[i + 1] - HB_STRING_ARRAY_OFFS_NAME[i] - 1);
+}
+
+#undef HB_STRING_ARRAY_TYPE_NAME
+#undef HB_STRING_ARRAY_POOL_NAME
+#undef HB_STRING_ARRAY_OFFS_NAME
+
+#endif /* HB_STRING_ARRAY_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh
index a4d118b6dc..82bb9a4ddc 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh
@@ -108,7 +108,7 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
/* XXX This hack belongs to the Myanmar shaper. */
if (unlikely (unicode == 0x1037u)) unicode = 0x103Au;
- /* XXX This hack belongs to the SEA shaper (for Tai Tham):
+ /* XXX This hack belongs to the USE shaper (for Tai Tham):
* Reorder SAKOT to ensure it comes after any tone marks. */
if (unlikely (unicode == 0x1A60u)) return 254;
@@ -126,7 +126,7 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
{
/* U+180B..180D MONGOLIAN FREE VARIATION SELECTORs are handled in the
* Arabic shaper. No need to match them here. */
- return unlikely (hb_in_ranges (unicode,
+ return unlikely (hb_in_ranges<hb_codepoint_t> (unicode,
0xFE00u, 0xFE0Fu, /* VARIATION SELECTOR-1..16 */
0xE0100u, 0xE01EFu)); /* VARIATION SELECTOR-17..256 */
}
@@ -137,6 +137,7 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
* we do NOT want to hide them, as the way Uniscribe has implemented them
* is with regular spacing glyphs, and that's the way fonts are made to work.
* As such, we make exceptions for those four.
+ * Also ignoring U+1BCA0..1BCA3. https://github.com/harfbuzz/harfbuzz/issues/503
*
* Unicode 7.0:
* $ grep '; Default_Ignorable_Code_Point ' DerivedCoreProperties.txt | sed 's/;.*#/#/'
@@ -179,13 +180,13 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
case 0x00: return unlikely (ch == 0x00ADu);
case 0x03: return unlikely (ch == 0x034Fu);
case 0x06: return unlikely (ch == 0x061Cu);
- case 0x17: return hb_in_range (ch, 0x17B4u, 0x17B5u);
- case 0x18: return hb_in_range (ch, 0x180Bu, 0x180Eu);
- case 0x20: return hb_in_ranges (ch, 0x200Bu, 0x200Fu,
+ case 0x17: return hb_in_range<hb_codepoint_t> (ch, 0x17B4u, 0x17B5u);
+ case 0x18: return hb_in_range<hb_codepoint_t> (ch, 0x180Bu, 0x180Eu);
+ case 0x20: return hb_in_ranges<hb_codepoint_t> (ch, 0x200Bu, 0x200Fu,
0x202Au, 0x202Eu,
0x2060u, 0x206Fu);
- case 0xFE: return hb_in_range (ch, 0xFE00u, 0xFE0Fu) || ch == 0xFEFFu;
- case 0xFF: return hb_in_range (ch, 0xFFF0u, 0xFFF8u);
+ case 0xFE: return hb_in_range<hb_codepoint_t> (ch, 0xFE00u, 0xFE0Fu) || ch == 0xFEFFu;
+ case 0xFF: return hb_in_range<hb_codepoint_t> (ch, 0xFFF0u, 0xFFF8u);
default: return false;
}
}
@@ -193,9 +194,8 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
{
/* Other planes */
switch (plane) {
- case 0x01: return hb_in_ranges (ch, 0x1BCA0u, 0x1BCA3u,
- 0x1D173u, 0x1D17Au);
- case 0x0E: return hb_in_range (ch, 0xE0000u, 0xE0FFFu);
+ case 0x01: return hb_in_range<hb_codepoint_t> (ch, 0x1D173u, 0x1D17Au);
+ case 0x0E: return hb_in_range<hb_codepoint_t> (ch, 0xE0000u, 0xE0FFFu);
default: return false;
}
}
@@ -346,23 +346,24 @@ extern HB_INTERNAL const hb_unicode_funcs_t _hb_unicode_funcs_nil;
#define HB_MODIFIED_COMBINING_CLASS_CCC122 122 /* mai * */
/* Tibetan
- * Modify U+0F74 (ccc=132) to reorder before ccc=130 marks.
+ *
+ * In case of multiple vowel-signs, use u first (but after achung)
+ * this allows Dzongkha multi-vowel shortcuts to render correctly
*/
#define HB_MODIFIED_COMBINING_CLASS_CCC129 129 /* sign aa */
-#define HB_MODIFIED_COMBINING_CLASS_CCC130 130 /* sign i */
-#define HB_MODIFIED_COMBINING_CLASS_CCC132 128 /* sign u */
-
+#define HB_MODIFIED_COMBINING_CLASS_CCC130 132 /* sign i */
+#define HB_MODIFIED_COMBINING_CLASS_CCC132 131 /* sign u */
/* Misc */
#define HB_UNICODE_GENERAL_CATEGORY_IS_MARK(gen_cat) \
- (FLAG_SAFE (gen_cat) & \
+ (FLAG_UNSAFE (gen_cat) & \
(FLAG (HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK) | \
FLAG (HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | \
FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)))
#define HB_UNICODE_GENERAL_CATEGORY_IS_NON_ENCLOSING_MARK_OR_MODIFIER_SYMBOL(gen_cat) \
- (FLAG_SAFE (gen_cat) & \
+ (FLAG_UNSAFE (gen_cat) & \
(FLAG (HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK) | \
FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) | \
FLAG (HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL)))
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc b/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc
index d553a7172f..726baeb0f1 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc
@@ -188,7 +188,7 @@ hb_unicode_funcs_create (hb_unicode_funcs_t *parent)
const hb_unicode_funcs_t _hb_unicode_funcs_nil = {
HB_OBJECT_HEADER_STATIC,
- NULL, /* parent */
+ nullptr, /* parent */
true, /* immutable */
{
#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_nil,
@@ -365,7 +365,7 @@ hb_unicode_funcs_set_##name##_func (hb_unicode_funcs_t *ufuncs, \
} else { \
ufuncs->func.name = ufuncs->parent->func.name; \
ufuncs->user_data.name = ufuncs->parent->user_data.name; \
- ufuncs->destroy.name = NULL; \
+ ufuncs->destroy.name = nullptr; \
} \
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-utf-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-utf-private.hh
index 74cf5d66a2..211eb4dc02 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-utf-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-utf-private.hh
@@ -48,7 +48,7 @@ struct hb_utf8_t
if (c > 0x7Fu)
{
- if (hb_in_range (c, 0xC2u, 0xDFu)) /* Two-byte */
+ if (hb_in_range<hb_codepoint_t> (c, 0xC2u, 0xDFu)) /* Two-byte */
{
unsigned int t1;
if (likely (text < end &&
@@ -60,7 +60,7 @@ struct hb_utf8_t
else
goto error;
}
- else if (hb_in_range (c, 0xE0u, 0xEFu)) /* Three-byte */
+ else if (hb_in_range<hb_codepoint_t> (c, 0xE0u, 0xEFu)) /* Three-byte */
{
unsigned int t1, t2;
if (likely (1 < end - text &&
@@ -68,14 +68,14 @@ struct hb_utf8_t
(t2 = text[1] - 0x80u) <= 0x3Fu))
{
c = ((c&0xFu)<<12) | (t1<<6) | t2;
- if (unlikely (c < 0x0800u || hb_in_range (c, 0xD800u, 0xDFFFu)))
+ if (unlikely (c < 0x0800u || hb_in_range<hb_codepoint_t> (c, 0xD800u, 0xDFFFu)))
goto error;
text += 2;
}
else
goto error;
}
- else if (hb_in_range (c, 0xF0u, 0xF4u)) /* Four-byte */
+ else if (hb_in_range<hb_codepoint_t> (c, 0xF0u, 0xF4u)) /* Four-byte */
{
unsigned int t1, t2, t3;
if (likely (2 < end - text &&
@@ -84,7 +84,7 @@ struct hb_utf8_t
(t3 = text[2] - 0x80u) <= 0x3Fu))
{
c = ((c&0x7u)<<18) | (t1<<12) | (t2<<6) | t3;
- if (unlikely (!hb_in_range (c, 0x10000u, 0x10FFFFu)))
+ if (unlikely (!hb_in_range<hb_codepoint_t> (c, 0x10000u, 0x10FFFFu)))
goto error;
text += 3;
}
@@ -140,7 +140,7 @@ struct hb_utf16_t
{
hb_codepoint_t c = *text++;
- if (likely (!hb_in_range (c, 0xD800u, 0xDFFFu)))
+ if (likely (!hb_in_range<hb_codepoint_t> (c, 0xD800u, 0xDFFFu)))
{
*unicode = c;
return text;
@@ -150,7 +150,7 @@ struct hb_utf16_t
{
/* High-surrogate in c */
hb_codepoint_t l = *text;
- if (likely (hb_in_range (l, 0xDC00u, 0xDFFFu)))
+ if (likely (hb_in_range<hb_codepoint_t> (l, 0xDC00u, 0xDFFFu)))
{
/* Low-surrogate in l */
*unicode = (c << 10) + l - ((0xD800u << 10) - 0x10000u + 0xDC00u);
@@ -172,7 +172,7 @@ struct hb_utf16_t
{
hb_codepoint_t c = *--text;
- if (likely (!hb_in_range (c, 0xD800u, 0xDFFFu)))
+ if (likely (!hb_in_range<hb_codepoint_t> (c, 0xD800u, 0xDFFFu)))
{
*unicode = c;
return text;
@@ -182,7 +182,7 @@ struct hb_utf16_t
{
/* Low-surrogate in c */
hb_codepoint_t h = text[-1];
- if (likely (hb_in_range (h, 0xD800u, 0xDBFFu)))
+ if (likely (hb_in_range<hb_codepoint_t> (h, 0xD800u, 0xDBFFu)))
{
/* High-surrogate in h */
*unicode = (h << 10) + c - ((0xD800u << 10) - 0x10000u + 0xDC00u);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-version.h b/src/3rdparty/harfbuzz-ng/src/hb-version.h
index 0cbe947062..fc81b66b40 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-version.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-version.h
@@ -37,10 +37,10 @@ HB_BEGIN_DECLS
#define HB_VERSION_MAJOR 1
-#define HB_VERSION_MINOR 4
-#define HB_VERSION_MICRO 1
+#define HB_VERSION_MINOR 7
+#define HB_VERSION_MICRO 4
-#define HB_VERSION_STRING "1.4.1"
+#define HB_VERSION_STRING "1.7.4"
#define HB_VERSION_ATLEAST(major,minor,micro) \
((major)*10000+(minor)*100+(micro) <= \